|
1
|
|
|
/*! |
|
2
|
|
|
* @name ElkArte Forum |
|
3
|
|
|
* @copyright ElkArte Forum contributors |
|
4
|
|
|
* @license BSD http://opensource.org/licenses/BSD-3-Clause |
|
5
|
|
|
* |
|
6
|
|
|
* This file contains code covered by: |
|
7
|
|
|
* copyright: 2011 Simple Machines (http://www.simplemachines.org) |
|
8
|
|
|
* license: BSD, See included LICENSE.TXT for terms and conditions. |
|
9
|
|
|
* |
|
10
|
|
|
* @version 1.1 |
|
11
|
|
|
*/ |
|
12
|
|
|
|
|
13
|
|
|
/** |
|
14
|
|
|
* Handle the JavaScript surrounding the admin and moderation center. |
|
15
|
|
|
*/ |
|
16
|
|
|
|
|
17
|
|
|
/** |
|
18
|
|
|
* We like the globals cuz they is good to us |
|
19
|
|
|
*/ |
|
20
|
|
|
|
|
21
|
|
|
/** global: previewTimeout, origText, valid, warningMessage, previewData, refreshPreviewCache, add_answer_template */ |
|
22
|
|
|
/** global: txt_add_another_answer, last_preview, txt_preview, elk_scripturl, txt_news_error_no_news, oThumbnails, elk_smiley_url */ |
|
23
|
|
|
/** global: db_vis, database_changes_area, elk_session_var, package_ftp_test, package_ftp_test_connection, package_ftp_test_failed */ |
|
24
|
|
|
/** global: onNewFolderReceived, elk_session_id, membersSwap, elk_images_url, maintain_members_choose, maintain_members_all */ |
|
25
|
|
|
/** global: reattribute_confirm, reattribute_confirm_email, reattribute_confirm_username, oModeratorSuggest, permission_profiles */ |
|
26
|
|
|
/** global: txt_save, txt_permissions_profile_rename, ajax_notification_cancel_text, txt_theme_remove_confirm, XMLHttpRequest */ |
|
27
|
|
|
/** global: theme_id, frames, editFilename, txt_ban_name_empty, txt_ban_restriction_empty, ElkInfoBar, txt_invalid_response */ |
|
28
|
|
|
/** global: feature_on_text, feature_off_text, core_settings_generic_error, startOptID, add_question_template, question_last_blank */ |
|
29
|
|
|
/** global: ourLanguageVersions, ourVersions, txt_add_another_answer, txt_permissions_commit, Image */ |
|
30
|
|
|
|
|
31
|
|
|
/** |
|
32
|
|
|
* Admin index class with the following methods |
|
33
|
|
|
* elk_AdminIndex(oOptions) |
|
34
|
|
|
* { |
|
35
|
|
|
* public init() |
|
36
|
|
|
* public loadAdminIndex() |
|
37
|
|
|
* public setAnnouncements() |
|
38
|
|
|
* public showCurrentVersion() |
|
39
|
|
|
* public checkUpdateAvailable() |
|
40
|
|
|
* } |
|
41
|
|
|
* |
|
42
|
|
|
* @param {object} oOptions |
|
43
|
|
|
*/ |
|
44
|
|
|
function elk_AdminIndex(oOptions) |
|
45
|
|
|
{ |
|
46
|
|
|
this.opt = oOptions; |
|
47
|
|
|
this.announcements = []; |
|
48
|
|
|
this.current = {}; |
|
49
|
|
|
this.init_news = false; |
|
50
|
|
|
this.init(); |
|
51
|
|
|
} |
|
52
|
|
|
|
|
53
|
|
|
// Initialize the admin index to handle announcement, current version and updates |
|
54
|
|
|
elk_AdminIndex.prototype.init = function () |
|
55
|
|
|
{ |
|
56
|
|
|
window.adminIndexInstanceRef = this; |
|
57
|
|
|
|
|
58
|
|
|
var fHandlePageLoaded = function () { |
|
59
|
|
|
window.adminIndexInstanceRef.loadAdminIndex(); |
|
60
|
|
|
}; |
|
61
|
|
|
|
|
62
|
|
|
addLoadEvent(fHandlePageLoaded); |
|
63
|
|
|
}; |
|
64
|
|
|
|
|
65
|
|
|
elk_AdminIndex.prototype.loadAdminIndex = function () |
|
66
|
|
|
{ |
|
67
|
|
|
// Load the current master and your version numbers. |
|
68
|
|
|
if (this.opt.bLoadVersions) |
|
69
|
|
|
this.showCurrentVersion(); |
|
|
|
|
|
|
70
|
|
|
|
|
71
|
|
|
// Load the text box that says there's a new version available. |
|
72
|
|
|
if (this.opt.bLoadUpdateNotification) |
|
73
|
|
|
this.checkUpdateAvailable(); |
|
|
|
|
|
|
74
|
|
|
}; |
|
75
|
|
|
|
|
76
|
|
|
// Update the announcement container with news |
|
77
|
|
|
elk_AdminIndex.prototype.setAnnouncement = function (announcement) |
|
78
|
|
|
{ |
|
79
|
|
|
var oElem = document.getElementById(this.opt.sAnnouncementContainerId), |
|
80
|
|
|
sMessages = this.init_news ? oElem.innerHTML : '', |
|
81
|
|
|
sMessage = ''; |
|
82
|
|
|
|
|
83
|
|
|
sMessage = this.opt.sAnnouncementMessageTemplate.replace('%href%', announcement.html_url).replace('%subject%', announcement.name).replace('%time%', announcement.published_at.replace(/[TZ]/g, ' ')).replace('%message%', announcement.body).replace(/\n/g, '<br />').replace(/\r/g, ''); |
|
84
|
|
|
|
|
85
|
|
|
oElem.innerHTML = sMessages + this.opt.sAnnouncementTemplate.replace('%content%', sMessage); |
|
86
|
|
|
this.init_news = true; |
|
87
|
|
|
}; |
|
88
|
|
|
|
|
89
|
|
|
// Updates the current version container with the current version found in the repository |
|
90
|
|
|
elk_AdminIndex.prototype.showCurrentVersion = function () |
|
91
|
|
|
{ |
|
92
|
|
|
var oElkVersionContainer = document.getElementById(this.opt.slatestVersionContainerId), |
|
93
|
|
|
oinstalledVersionContainer = document.getElementById(this.opt.sinstalledVersionContainerId), |
|
94
|
|
|
sCurrentVersion = oinstalledVersionContainer.innerHTML, |
|
95
|
|
|
adminIndex = this, |
|
96
|
|
|
elkVersion = '???', |
|
97
|
|
|
verCompare = new elk_ViewVersions(); |
|
|
|
|
|
|
98
|
|
|
|
|
99
|
|
|
$.getJSON('https://api.github.com/repos/elkarte/Elkarte/releases', {format: "json"}, |
|
100
|
|
|
function(data, textStatus, jqXHR) { |
|
|
|
|
|
|
101
|
|
|
var mostRecent = {}, |
|
102
|
|
|
previous = {}; |
|
103
|
|
|
adminIndex.current = adminIndex.normalizeVersion(sCurrentVersion); |
|
104
|
|
|
|
|
105
|
|
|
$.each(data, function(idx, elem) { |
|
106
|
|
|
// No drafts, thank you |
|
107
|
|
|
if (elem.draft) |
|
108
|
|
|
return; |
|
|
|
|
|
|
109
|
|
|
|
|
110
|
|
|
var release = adminIndex.normalizeVersion(elem.tag_name); |
|
111
|
|
|
|
|
112
|
|
|
if (!previous.hasOwnProperty('major') || verCompare.compareVersions(sCurrentVersion, elem.tag_name.replace('-', '').substring(1))) |
|
113
|
|
|
{ |
|
114
|
|
|
// Using a preprelease? Then you may need to know a new one is out! |
|
115
|
|
|
if ((elem.prerelease && adminIndex.current.prerelease) || (!elem.prerelease)) |
|
116
|
|
|
{ |
|
117
|
|
|
previous = release; |
|
118
|
|
|
mostRecent = elem; |
|
119
|
|
|
} |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
// Load the text box containing the latest news items. |
|
123
|
|
|
if (adminIndex.opt.bLoadAnnouncements) |
|
124
|
|
|
adminIndex.setAnnouncement(elem); |
|
|
|
|
|
|
125
|
|
|
}); |
|
126
|
|
|
elkVersion = mostRecent.name.replace(/elkarte/i, '').trim(); |
|
127
|
|
|
|
|
128
|
|
|
oElkVersionContainer.innerHTML = elkVersion; |
|
129
|
|
|
if (verCompare.compareVersions(sCurrentVersion, elkVersion)) |
|
130
|
|
|
oinstalledVersionContainer.innerHTML = adminIndex.opt.sVersionOutdatedTemplate.replace('%currentVersion%', sCurrentVersion); |
|
|
|
|
|
|
131
|
|
|
}); |
|
132
|
|
|
}; |
|
133
|
|
|
|
|
134
|
|
|
// Compare two different versions and return true if the firs is higher than the second |
|
135
|
|
|
elk_AdminIndex.prototype.compareVersion = function (curVer, refVer) |
|
136
|
|
|
{ |
|
137
|
|
|
if (curVer.major > refVer.major) |
|
138
|
|
|
return true; |
|
|
|
|
|
|
139
|
|
|
else if (curVer.major < refVer.major) |
|
140
|
|
|
return false; |
|
|
|
|
|
|
141
|
|
|
|
|
142
|
|
|
if (curVer.minor > refVer.minor) |
|
143
|
|
|
return true; |
|
|
|
|
|
|
144
|
|
|
else if (curVer.minor < refVer.minor) |
|
145
|
|
|
return false; |
|
|
|
|
|
|
146
|
|
|
|
|
147
|
|
|
if (curVer.micro > refVer.micro) |
|
148
|
|
|
return true; |
|
|
|
|
|
|
149
|
|
|
else if (curVer.micro < refVer.micro) |
|
150
|
|
|
return false; |
|
|
|
|
|
|
151
|
|
|
|
|
152
|
|
|
if (curVer.prerelease) |
|
153
|
|
|
{ |
|
154
|
|
|
if (curVer.nano > refVer.nano) |
|
155
|
|
|
return true; |
|
|
|
|
|
|
156
|
|
|
else if (curVer.nano < refVer.nano) |
|
157
|
|
|
return false; |
|
|
|
|
|
|
158
|
|
|
} |
|
159
|
|
|
|
|
160
|
|
|
return false; |
|
161
|
|
|
}; |
|
162
|
|
|
|
|
163
|
|
|
// Split a string representing a version number into an object |
|
164
|
|
|
elk_AdminIndex.prototype.normalizeVersion = function (sVersion) |
|
165
|
|
|
{ |
|
166
|
|
|
var splitVersion = sVersion.split(/[\s-]/), |
|
167
|
|
|
normalVersion = { |
|
168
|
|
|
major: 0, |
|
169
|
|
|
minor: 0, |
|
170
|
|
|
micro: 0, |
|
171
|
|
|
prerelease: false, |
|
172
|
|
|
status: 0, |
|
173
|
|
|
nano: 0 |
|
174
|
|
|
}, |
|
175
|
|
|
prerelease = false, |
|
176
|
|
|
aDevConvert = {'dev': 0, 'alpha': 1, 'beta': 2, 'rc': 3, 'stable': 4}; |
|
177
|
|
|
|
|
178
|
|
|
for (var i = 0; i < splitVersion.length; i++) |
|
179
|
|
|
{ |
|
180
|
|
|
if (splitVersion[i].toLowerCase() === 'elkarte') |
|
181
|
|
|
continue; |
|
|
|
|
|
|
182
|
|
|
|
|
183
|
|
|
if (splitVersion[i].substring(0, 3).toLowerCase() === 'dev' || splitVersion[i].substring(0, 5).toLowerCase() === 'alpha' || splitVersion[i].substring(0, 4).toLowerCase() === 'beta' || splitVersion[i].substring(0, 2).toLowerCase() === 'rc') |
|
184
|
|
|
{ |
|
185
|
|
|
normalVersion.prerelease = true; |
|
186
|
|
|
prerelease = true; |
|
187
|
|
|
|
|
188
|
|
|
// the tag name comes with the number attached to the beta/rc |
|
189
|
|
|
if (splitVersion[i].indexOf('.') > 0) |
|
190
|
|
|
{ |
|
191
|
|
|
var splitPre = splitVersion[i].split('.'); |
|
192
|
|
|
normalVersion.nano = parseFloat(splitPre[1]); |
|
193
|
|
|
normalVersion.nano = parseFloat(splitVersion[i].substr(splitVersion[i].indexOf('.') + 1)); |
|
194
|
|
|
normalVersion.status = aDevConvert[splitVersion[i].substr(0, splitVersion[i].indexOf('.')).toLowerCase()]; |
|
195
|
|
|
} |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
// If we have passed a "beta" or an "RC" string, no need to go further |
|
199
|
|
|
if (prerelease) |
|
200
|
|
|
{ |
|
201
|
|
|
// Only numbers and dots means a number |
|
202
|
|
|
if (splitVersion[i].replace(/[\d\.]/g, '') === '') |
|
203
|
|
|
normalVersion.nano = parseFloat(splitVersion[i]); |
|
|
|
|
|
|
204
|
|
|
|
|
205
|
|
|
continue; |
|
206
|
|
|
} |
|
207
|
|
|
|
|
208
|
|
|
// Likely from the tag |
|
209
|
|
|
if (splitVersion[i].substring(0, 1) === 'v') |
|
210
|
|
|
splitVersion[i] = splitVersion[i].substring(1); |
|
|
|
|
|
|
211
|
|
|
|
|
212
|
|
|
// Only numbers and dots means a number |
|
213
|
|
|
if (splitVersion[i].replace(/[\d\.]/g, '') === '') |
|
214
|
|
|
{ |
|
215
|
|
|
var ver = splitVersion[i].split('.'); |
|
216
|
|
|
normalVersion.major = parseInt(ver[0]); |
|
217
|
|
|
normalVersion.minor = parseInt(ver[1]); |
|
218
|
|
|
normalVersion.micro = ver.length > 2 ? parseInt(ver[2]) : 0; |
|
219
|
|
|
} |
|
220
|
|
|
} |
|
221
|
|
|
return normalVersion; |
|
222
|
|
|
}; |
|
223
|
|
|
|
|
224
|
|
|
// Checks if a new version of ElkArte is available and if so updates the admin info box |
|
225
|
|
|
elk_AdminIndex.prototype.checkUpdateAvailable = function () |
|
226
|
|
|
{ |
|
227
|
|
|
if (!('ourUpdatePackage' in window)) |
|
228
|
|
|
return; |
|
|
|
|
|
|
229
|
|
|
|
|
230
|
|
|
var oContainer = document.getElementById(this.opt.sUpdateNotificationContainerId); |
|
231
|
|
|
|
|
232
|
|
|
// Are we setting a custom title and message? |
|
233
|
|
|
var sTitle = 'ourUpdateTitle' in window ? window.ourUpdateTitle : this.opt.sUpdateNotificationDefaultTitle, |
|
234
|
|
|
sMessage = 'ourUpdateNotice' in window ? window.ourUpdateNotice : this.opt.sUpdateNotificationDefaultMessage; |
|
235
|
|
|
|
|
236
|
|
|
oContainer.innerHTML = this.opt.sUpdateNotificationTemplate.replace('%title%', sTitle).replace('%message%', sMessage); |
|
237
|
|
|
|
|
238
|
|
|
// Parse in the package download URL if it exists in the string. |
|
239
|
|
|
document.getElementById('update-link').href = this.opt.sUpdateNotificationLink.replace('%package%', window.ourUpdatePackage); |
|
240
|
|
|
|
|
241
|
|
|
// If we decide to override life into "red" mode, do it. |
|
242
|
|
|
if ('elkUpdateCritical' in window) |
|
243
|
|
|
{ |
|
244
|
|
|
document.getElementById('update_title').style.backgroundColor = '#dd2222'; |
|
245
|
|
|
document.getElementById('update_title').style.color = 'white'; |
|
246
|
|
|
document.getElementById('update_message').style.backgroundColor = '#eebbbb'; |
|
247
|
|
|
document.getElementById('update_message').style.color = 'black'; |
|
248
|
|
|
} |
|
249
|
|
|
}; |
|
250
|
|
|
|
|
251
|
|
|
/* |
|
252
|
|
|
elk_ViewVersions(oOptions) |
|
253
|
|
|
{ |
|
254
|
|
|
public init() |
|
255
|
|
|
public loadViewVersions |
|
256
|
|
|
public swapOption(oSendingElement, sName) |
|
257
|
|
|
public compareVersions(sCurrent, sTarget) |
|
258
|
|
|
public determineVersions() |
|
259
|
|
|
} |
|
260
|
|
|
*/ |
|
261
|
|
|
function elk_ViewVersions (oOptions) |
|
262
|
|
|
{ |
|
263
|
|
|
this.opt = oOptions; |
|
264
|
|
|
this.oSwaps = {}; |
|
265
|
|
|
this.init(); |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
// initialize the version checker |
|
269
|
|
|
elk_ViewVersions.prototype.init = function () |
|
270
|
|
|
{ |
|
271
|
|
|
// Load this on loading of the page. |
|
272
|
|
|
window.viewVersionsInstanceRef = this; |
|
273
|
|
|
var fHandlePageLoaded = function () { |
|
274
|
|
|
window.viewVersionsInstanceRef.loadViewVersions(); |
|
275
|
|
|
}; |
|
276
|
|
|
addLoadEvent(fHandlePageLoaded); |
|
277
|
|
|
}; |
|
278
|
|
|
|
|
279
|
|
|
// Load all the file versions |
|
280
|
|
|
elk_ViewVersions.prototype.loadViewVersions = function () |
|
281
|
|
|
{ |
|
282
|
|
|
this.determineVersions(); |
|
283
|
|
|
}; |
|
284
|
|
|
|
|
285
|
|
|
elk_ViewVersions.prototype.swapOption = function (oSendingElement, sName) |
|
286
|
|
|
{ |
|
287
|
|
|
// If it is undefined, or currently off, turn it on - otherwise off. |
|
288
|
|
|
this.oSwaps[sName] = !(sName in this.oSwaps) || !this.oSwaps[sName]; |
|
289
|
|
|
if (this.oSwaps[sName]) |
|
290
|
|
|
$("#" + sName).show(300); |
|
|
|
|
|
|
291
|
|
|
else |
|
292
|
|
|
$("#" + sName).hide(300); |
|
293
|
|
|
|
|
294
|
|
|
// Unselect the link and return false. |
|
295
|
|
|
oSendingElement.blur(); |
|
296
|
|
|
|
|
297
|
|
|
return false; |
|
298
|
|
|
}; |
|
299
|
|
|
|
|
300
|
|
|
// compare a current and target version to determine if one is newer/older |
|
301
|
|
|
elk_ViewVersions.prototype.compareVersions = function (sCurrent, sTarget) |
|
302
|
|
|
{ |
|
303
|
|
|
var aVersions = [], |
|
304
|
|
|
aParts = [], |
|
|
|
|
|
|
305
|
|
|
aCompare = [sCurrent, sTarget], |
|
306
|
|
|
aDevConvert = {'dev': 0, 'alpha': 1, 'beta': 2, 'rc': 3}; |
|
307
|
|
|
|
|
308
|
|
|
for (var i = 0; i < 2; i++) |
|
309
|
|
|
{ |
|
310
|
|
|
// Clean the version and extract the version parts. |
|
311
|
|
|
var sClean = aCompare[i].toLowerCase().replace(/ /g, '').replace(/release candidate/g, 'rc'); |
|
312
|
|
|
aParts = sClean.match(/(\d+)(?:\.(\d+|))?(?:\.)?(\d+|)(?:(alpha|beta|rc)\.*(\d+|)(?:\.)?(\d+|))?(?:(dev))?(\d+|)/); |
|
313
|
|
|
|
|
314
|
|
|
// No matches? |
|
315
|
|
|
if (aParts === null) |
|
316
|
|
|
return false; |
|
|
|
|
|
|
317
|
|
|
|
|
318
|
|
|
// Build an array of parts. |
|
319
|
|
|
aVersions[i] = [ |
|
320
|
|
|
aParts[1] > 0 ? parseInt(aParts[1]) : 0, |
|
321
|
|
|
aParts[2] > 0 ? parseInt(aParts[2]) : 0, |
|
322
|
|
|
aParts[3] > 0 ? parseInt(aParts[3]) : 0, |
|
323
|
|
|
typeof(aParts[4]) === 'undefined' ? 'stable' : aDevConvert[aParts[4]], |
|
324
|
|
|
aParts[5] > 0 ? parseInt(aParts[5]) : 0, |
|
325
|
|
|
aParts[6] > 0 ? parseInt(aParts[6]) : 0, |
|
326
|
|
|
typeof(aParts[7]) !== 'undefined' ? 'dev' : '' |
|
327
|
|
|
]; |
|
328
|
|
|
} |
|
329
|
|
|
|
|
330
|
|
|
// Loop through each category. |
|
331
|
|
|
for (i = 0; i < 7; i++) |
|
332
|
|
|
{ |
|
333
|
|
|
// Is there something for us to calculate? |
|
334
|
|
|
if (aVersions[0][i] !== aVersions[1][i]) |
|
335
|
|
|
{ |
|
336
|
|
|
// Dev builds are a problematic exception. |
|
337
|
|
|
// (stable) dev < (stable) but (unstable) dev = (unstable) |
|
338
|
|
|
if (i === 3) |
|
339
|
|
|
return aVersions[0][i] < aVersions[1][i] ? !aVersions[1][6] : aVersions[0][6]; |
|
|
|
|
|
|
340
|
|
|
else if (i === 6) |
|
341
|
|
|
return aVersions[0][6] ? aVersions[1][3] === 'stable' : false; |
|
|
|
|
|
|
342
|
|
|
// Otherwise a simple comparison. |
|
343
|
|
|
else |
|
344
|
|
|
return aVersions[0][i] < aVersions[1][i]; |
|
345
|
|
|
} |
|
346
|
|
|
} |
|
347
|
|
|
|
|
348
|
|
|
// They are the same! |
|
349
|
|
|
return false; |
|
350
|
|
|
}; |
|
351
|
|
|
|
|
352
|
|
|
// For each area of ElkArte, determine the current and installed versions |
|
353
|
|
|
elk_ViewVersions.prototype.determineVersions = function () |
|
354
|
|
|
{ |
|
355
|
|
|
var oHighYour = { |
|
356
|
|
|
sources: '??', |
|
357
|
|
|
admin: '??', |
|
358
|
|
|
controllers: '??', |
|
359
|
|
|
database: '??', |
|
360
|
|
|
subs: '??', |
|
361
|
|
|
'default': '??', |
|
362
|
|
|
Languages: '??', |
|
363
|
|
|
Templates: '??' |
|
364
|
|
|
}; |
|
365
|
|
|
var oHighCurrent = { |
|
366
|
|
|
sources: '??', |
|
367
|
|
|
admin: '??', |
|
368
|
|
|
controllers: '??', |
|
369
|
|
|
database: '??', |
|
370
|
|
|
subs: '??', |
|
371
|
|
|
'default': '??', |
|
372
|
|
|
Languages: '??', |
|
373
|
|
|
Templates: '??' |
|
374
|
|
|
}; |
|
375
|
|
|
var oLowVersion = { |
|
376
|
|
|
sources: false, |
|
377
|
|
|
admin: false, |
|
378
|
|
|
controllers: false, |
|
379
|
|
|
database: false, |
|
380
|
|
|
subs: false, |
|
381
|
|
|
'default': false, |
|
382
|
|
|
Languages: false, |
|
383
|
|
|
Templates: false |
|
384
|
|
|
}; |
|
385
|
|
|
|
|
386
|
|
|
var sSections = [ |
|
387
|
|
|
'sources', |
|
388
|
|
|
'admin', |
|
389
|
|
|
'controllers', |
|
390
|
|
|
'database', |
|
391
|
|
|
'subs', |
|
392
|
|
|
'default', |
|
393
|
|
|
'Languages', |
|
394
|
|
|
'Templates' |
|
395
|
|
|
]; |
|
396
|
|
|
|
|
397
|
|
|
var sCurVersionType = '', |
|
398
|
|
|
sinstalledVersion, |
|
399
|
|
|
oSection, |
|
400
|
|
|
oSectionLink; |
|
401
|
|
|
|
|
402
|
|
|
for (var i = 0, n = sSections.length; i < n; i++) |
|
403
|
|
|
{ |
|
404
|
|
|
// Collapse all sections. |
|
405
|
|
|
oSection = document.getElementById(sSections[i]); |
|
406
|
|
|
|
|
407
|
|
|
if (typeof(oSection) === 'object' && oSection !== null) |
|
408
|
|
|
oSection.style.display = 'none'; |
|
|
|
|
|
|
409
|
|
|
|
|
410
|
|
|
// Make all section links clickable. |
|
411
|
|
|
oSectionLink = document.getElementById(sSections[i] + '-link'); |
|
412
|
|
|
if (typeof(oSectionLink) === 'object' && oSectionLink !== null) |
|
413
|
|
|
{ |
|
414
|
|
|
oSectionLink.instanceRef = this; |
|
415
|
|
|
oSectionLink.sSection = sSections[i]; |
|
416
|
|
|
oSectionLink.onclick = function () { |
|
417
|
|
|
this.instanceRef.swapOption(this, this.sSection); |
|
418
|
|
|
return false; |
|
419
|
|
|
}; |
|
420
|
|
|
} |
|
421
|
|
|
} |
|
422
|
|
|
|
|
423
|
|
|
if (!('ourVersions' in window)) |
|
424
|
|
|
window.ourVersions = {}; |
|
|
|
|
|
|
425
|
|
|
|
|
426
|
|
|
// for each file in the detailed-version.js |
|
427
|
|
|
for (var sFilename in window.ourVersions) |
|
428
|
|
|
{ |
|
429
|
|
|
if (!window.ourVersions.hasOwnProperty(sFilename)) |
|
430
|
|
|
continue; |
|
|
|
|
|
|
431
|
|
|
|
|
432
|
|
|
if (!document.getElementById('our' + sFilename)) |
|
433
|
|
|
continue; |
|
|
|
|
|
|
434
|
|
|
|
|
435
|
|
|
sCurVersionType = ''; |
|
436
|
|
|
|
|
437
|
|
|
sinstalledVersion = document.getElementById('your' + sFilename).innerHTML; |
|
438
|
|
|
|
|
439
|
|
|
for (var sVersionType in oLowVersion) |
|
440
|
|
|
{ |
|
441
|
|
|
if (!oLowVersion.hasOwnProperty(sVersionType)) |
|
442
|
|
|
{ |
|
443
|
|
|
continue; |
|
444
|
|
|
} |
|
445
|
|
|
|
|
446
|
|
|
if (sFilename.substr(0, sVersionType.length) === sVersionType) |
|
447
|
|
|
{ |
|
448
|
|
|
sCurVersionType = sVersionType; |
|
449
|
|
|
break; |
|
450
|
|
|
} |
|
451
|
|
|
} |
|
452
|
|
|
|
|
453
|
|
|
if (sCurVersionType === '') |
|
454
|
|
|
continue; |
|
|
|
|
|
|
455
|
|
|
|
|
456
|
|
|
// use compareVersion to determine which version is >< the other |
|
457
|
|
|
if (typeof(sCurVersionType) !== 'undefined') |
|
458
|
|
|
{ |
|
459
|
|
|
if ((this.compareVersions(oHighYour[sCurVersionType], sinstalledVersion) || oHighYour[sCurVersionType] === '??') && !oLowVersion[sCurVersionType]) |
|
460
|
|
|
oHighYour[sCurVersionType] = sinstalledVersion; |
|
|
|
|
|
|
461
|
|
|
|
|
462
|
|
|
if (this.compareVersions(oHighCurrent[sCurVersionType], ourVersions[sFilename]) || oHighCurrent[sCurVersionType] === '??') |
|
463
|
|
|
oHighCurrent[sCurVersionType] = ourVersions[sFilename]; |
|
|
|
|
|
|
464
|
|
|
|
|
465
|
|
|
if (this.compareVersions(sinstalledVersion, ourVersions[sFilename])) |
|
466
|
|
|
{ |
|
467
|
|
|
oLowVersion[sCurVersionType] = sinstalledVersion; |
|
468
|
|
|
document.getElementById('your' + sFilename).style.color = 'red'; |
|
469
|
|
|
} |
|
470
|
|
|
} |
|
471
|
|
|
else if (this.compareVersions(sinstalledVersion, ourVersions[sFilename])) |
|
472
|
|
|
oLowVersion[sCurVersionType] = sinstalledVersion; |
|
|
|
|
|
|
473
|
|
|
|
|
474
|
|
|
document.getElementById('our' + sFilename).innerHTML = ourVersions[sFilename]; |
|
475
|
|
|
document.getElementById('your' + sFilename).innerHTML = sinstalledVersion; |
|
476
|
|
|
} |
|
477
|
|
|
|
|
478
|
|
|
if (!('ourLanguageVersions' in window)) |
|
479
|
|
|
window.ourLanguageVersions = {}; |
|
|
|
|
|
|
480
|
|
|
|
|
481
|
|
|
for (sFilename in window.ourLanguageVersions) |
|
482
|
|
|
{ |
|
483
|
|
|
for (i = 0; i < this.opt.aKnownLanguages.length; i++) |
|
484
|
|
|
{ |
|
485
|
|
|
if (!document.getElementById('our' + sFilename + this.opt.aKnownLanguages[i])) |
|
486
|
|
|
continue; |
|
|
|
|
|
|
487
|
|
|
|
|
488
|
|
|
document.getElementById('our' + sFilename + this.opt.aKnownLanguages[i]).innerHTML = ourLanguageVersions[sFilename]; |
|
489
|
|
|
|
|
490
|
|
|
sinstalledVersion = document.getElementById('your' + sFilename + this.opt.aKnownLanguages[i]).innerHTML; |
|
491
|
|
|
document.getElementById('your' + sFilename + this.opt.aKnownLanguages[i]).innerHTML = sinstalledVersion; |
|
492
|
|
|
|
|
493
|
|
|
if ((this.compareVersions(oHighYour.Languages, sinstalledVersion) || oHighYour.Languages === '??') && !oLowVersion.Languages) |
|
494
|
|
|
oHighYour.Languages = sinstalledVersion; |
|
|
|
|
|
|
495
|
|
|
|
|
496
|
|
|
if (this.compareVersions(oHighCurrent.Languages, ourLanguageVersions[sFilename]) || oHighCurrent.Languages === '??') |
|
497
|
|
|
oHighCurrent.Languages = ourLanguageVersions[sFilename]; |
|
|
|
|
|
|
498
|
|
|
|
|
499
|
|
|
if (this.compareVersions(sinstalledVersion, ourLanguageVersions[sFilename])) |
|
500
|
|
|
{ |
|
501
|
|
|
oLowVersion.Languages = sinstalledVersion; |
|
502
|
|
|
document.getElementById('your' + sFilename + this.opt.aKnownLanguages[i]).style.color = 'red'; |
|
503
|
|
|
} |
|
504
|
|
|
} |
|
505
|
|
|
} |
|
506
|
|
|
|
|
507
|
|
|
// Set the column titles based on the files each contain |
|
508
|
|
|
for (i = 0, n = sSections.length; i < n; i++) |
|
509
|
|
|
{ |
|
510
|
|
|
if (sSections[i] === 'Templates') |
|
511
|
|
|
continue; |
|
|
|
|
|
|
512
|
|
|
|
|
513
|
|
|
document.getElementById('your' + sSections[i]).innerHTML = oLowVersion[sSections[i]] ? oLowVersion[sSections[i]] : oHighYour[sSections[i]]; |
|
514
|
|
|
document.getElementById('our' + sSections[i]).innerHTML = oHighCurrent[sSections[i]]; |
|
515
|
|
|
if (oLowVersion[sSections[i]]) |
|
516
|
|
|
document.getElementById('your' + sSections[i]).style.color = 'red'; |
|
|
|
|
|
|
517
|
|
|
} |
|
518
|
|
|
|
|
519
|
|
|
// Custom theme in use? |
|
520
|
|
|
if (document.getElementById('Templates')) |
|
521
|
|
|
{ |
|
522
|
|
|
document.getElementById('yourTemplates').innerHTML = oLowVersion.Templates ? oLowVersion.Templates : oHighYour.Templates; |
|
523
|
|
|
document.getElementById('ourTemplates').innerHTML = oHighCurrent.Templates; |
|
524
|
|
|
|
|
525
|
|
|
if (oLowVersion.Templates) |
|
526
|
|
|
document.getElementById('yourTemplates').style.color = 'red'; |
|
|
|
|
|
|
527
|
|
|
} |
|
528
|
|
|
}; |
|
529
|
|
|
|
|
530
|
|
|
/** |
|
531
|
|
|
* Adds a new word container to the censored word list |
|
532
|
|
|
*/ |
|
533
|
|
|
function addNewWord() |
|
534
|
|
|
{ |
|
535
|
|
|
setOuterHTML(document.getElementById('moreCensoredWords'), '<div class="censorWords"><input type="text" name="censor_vulgar[]" size="30" class="input_text" /> <i class="icon i-chevron-circle-right"></i> <input type="text" name="censor_proper[]" size="30" class="input_text" /><' + '/div><div id="moreCensoredWords"><' + '/div>'); |
|
536
|
|
|
} |
|
537
|
|
|
|
|
538
|
|
|
/** |
|
539
|
|
|
* Will enable/disable checkboxes, according to if the BBC globally set or not. |
|
540
|
|
|
* |
|
541
|
|
|
* @param {string} section id of the container |
|
542
|
|
|
* @param {string} disable true or false |
|
543
|
|
|
*/ |
|
544
|
|
|
function toggleBBCDisabled(section, disable) |
|
545
|
|
|
{ |
|
546
|
|
|
var elems = document.getElementById(section).getElementsByTagName('*'); |
|
547
|
|
|
|
|
548
|
|
|
for (var i = 0; i < elems.length; i++) |
|
549
|
|
|
{ |
|
550
|
|
|
if (typeof(elems[i].name) === "undefined" || (elems[i].name.substr((section.length + 1), (elems[i].name.length - 2 - (section.length + 1))) !== "enabledTags") || (elems[i].name.indexOf(section) !== 0)) |
|
551
|
|
|
continue; |
|
|
|
|
|
|
552
|
|
|
|
|
553
|
|
|
elems[i].disabled = disable; |
|
554
|
|
|
} |
|
555
|
|
|
document.getElementById("bbc_" + section + "_select_all").disabled = disable; |
|
556
|
|
|
} |
|
557
|
|
|
|
|
558
|
|
|
/** |
|
559
|
|
|
* Keeps the input boxes display options appropriate for the options selected |
|
560
|
|
|
* when adding custom profile fields |
|
561
|
|
|
*/ |
|
562
|
|
|
function updateInputBoxes() |
|
563
|
|
|
{ |
|
564
|
|
|
var curType = document.getElementById("field_type").value, |
|
565
|
|
|
privStatus = document.getElementById("private").value, |
|
566
|
|
|
stdText = ['text', 'textarea', 'email', 'url', 'color', 'date'], |
|
567
|
|
|
stdInput = ['text', 'email', 'url', 'color', 'date'], |
|
568
|
|
|
stdSelect = ['select']; |
|
569
|
|
|
|
|
570
|
|
|
var bIsStd = (stdInput.indexOf(curType) !== -1), |
|
571
|
|
|
bIsText = (stdText.indexOf(curType) !== -1), |
|
572
|
|
|
bIsSelect = (stdSelect.indexOf(curType) !== -1); |
|
573
|
|
|
|
|
574
|
|
|
// Only Text like fields can see a max length input |
|
575
|
|
|
document.getElementById("max_length_dt").style.display = bIsText ? "" : "none"; |
|
576
|
|
|
document.getElementById("max_length_dd").style.display = bIsText ? "" : "none"; |
|
577
|
|
|
|
|
578
|
|
|
// Textareas can get a row/col definition |
|
579
|
|
|
document.getElementById("dimension_dt").style.display = curType === "textarea" ? "" : "none"; |
|
580
|
|
|
document.getElementById("dimension_dd").style.display = curType === "textarea" ? "" : "none"; |
|
581
|
|
|
|
|
582
|
|
|
// Text like fields can be styled with bbc |
|
583
|
|
|
document.getElementById("bbc_dt").style.display = bIsText ? "" : "none"; |
|
584
|
|
|
document.getElementById("bbc_dd").style.display = bIsText ? "" : "none"; |
|
585
|
|
|
|
|
586
|
|
|
// And given defaults |
|
587
|
|
|
document.getElementById("defaultval_dt").style.display = bIsText ? "" : "none"; |
|
588
|
|
|
document.getElementById("defaultval_dd").style.display = bIsText ? "" : "none"; |
|
589
|
|
|
|
|
590
|
|
|
// Selects and radio can support a list of options |
|
591
|
|
|
document.getElementById("options_dt").style.display = curType === "select" || curType === "radio" ? "" : "none"; |
|
592
|
|
|
document.getElementById("options_dd").style.display = curType === "select" || curType === "radio" ? "" : "none"; |
|
593
|
|
|
|
|
594
|
|
|
// Checkboxes can have a default |
|
595
|
|
|
document.getElementById("default_dt").style.display = curType === "check" ? "" : "none"; |
|
596
|
|
|
document.getElementById("default_dd").style.display = curType === "check" ? "" : "none"; |
|
597
|
|
|
|
|
598
|
|
|
// Normal input boxes can use a validation mask as well |
|
599
|
|
|
document.getElementById("mask_dt").style.display = bIsStd ? "" : "none"; |
|
600
|
|
|
document.getElementById("mask").style.display = bIsStd ? "" : "none"; |
|
601
|
|
|
|
|
602
|
|
|
// And text and select fields are searchable |
|
603
|
|
|
document.getElementById("can_search_dt").style.display = bIsText || bIsSelect ? "" : "none"; |
|
604
|
|
|
document.getElementById("can_search_dd").style.display = bIsText || bIsSelect ? "" : "none"; |
|
605
|
|
|
|
|
606
|
|
|
// Moving to a non searchable field, be sure searchable is unselected. |
|
607
|
|
|
if (!bIsText && !bIsSelect) |
|
608
|
|
|
document.getElementById("can_search_dd").checked = false; |
|
|
|
|
|
|
609
|
|
|
|
|
610
|
|
|
// Using regex in the mask, give them a place to supply the regex |
|
611
|
|
|
document.getElementById("regex_div").style.display = bIsStd && document.getElementById("mask").value === "regex" ? "" : "none"; |
|
612
|
|
|
document.getElementById("display").disabled = false; |
|
613
|
|
|
|
|
614
|
|
|
// Cannot show this on the topic |
|
615
|
|
|
if (curType === "textarea" || privStatus >= 2) |
|
616
|
|
|
{ |
|
617
|
|
|
document.getElementById("display").checked = false; |
|
618
|
|
|
document.getElementById("display").disabled = true; |
|
619
|
|
|
} |
|
620
|
|
|
} |
|
621
|
|
|
|
|
622
|
|
|
/** |
|
623
|
|
|
* Used to add additional radio button options when editing a custom profile field |
|
624
|
|
|
*/ |
|
625
|
|
|
function addOption() |
|
626
|
|
|
{ |
|
627
|
|
|
setOuterHTML(document.getElementById("addopt"), '<p><input type="radio" name="default_select" value="' + startOptID + '" id="' + startOptID + '" /><input type="text" name="select_option[' + startOptID + ']" value="" class="input_text" /></p><span id="addopt"></span>'); |
|
628
|
|
|
startOptID++; |
|
629
|
|
|
} |
|
630
|
|
|
|
|
631
|
|
|
/** |
|
632
|
|
|
* Adds another question to the registration page |
|
633
|
|
|
*/ |
|
634
|
|
|
function addAnotherQuestion() |
|
635
|
|
|
{ |
|
636
|
|
|
var placeHolder = document.getElementById('add_more_question_placeholder'); |
|
637
|
|
|
|
|
638
|
|
|
setOuterHTML(placeHolder, add_question_template.easyReplace({ |
|
639
|
|
|
question_last_blank: question_last_blank, |
|
640
|
|
|
setup_verification_add_more_answers: txt_add_another_answer |
|
641
|
|
|
})); |
|
642
|
|
|
|
|
643
|
|
|
question_last_blank++; |
|
644
|
|
|
} |
|
645
|
|
|
|
|
646
|
|
|
/** |
|
647
|
|
|
* Every question should have an answer, even if its a lie |
|
648
|
|
|
* |
|
649
|
|
|
* @param {HTMLElement} elem |
|
650
|
|
|
* @param {string} question_name |
|
651
|
|
|
*/ |
|
652
|
|
|
function addAnotherAnswer(elem, question_name) |
|
653
|
|
|
{ |
|
654
|
|
|
setOuterHTML(elem, add_answer_template.easyReplace({ |
|
655
|
|
|
question_last_blank: question_name, |
|
656
|
|
|
setup_verification_add_more_answers: txt_add_another_answer |
|
657
|
|
|
})); |
|
658
|
|
|
} |
|
659
|
|
|
|
|
660
|
|
|
/** |
|
661
|
|
|
* Used to add new search engines to the known list |
|
662
|
|
|
* |
|
663
|
|
|
* @param {string} txt_name |
|
664
|
|
|
* @param {string} txt_url |
|
665
|
|
|
* @param {string} txt_word_sep |
|
666
|
|
|
*/ |
|
667
|
|
|
function addAnotherSearch(txt_name, txt_url, txt_word_sep) |
|
668
|
|
|
{ |
|
669
|
|
|
var placeHolder = document.getElementById('add_more_searches'), |
|
670
|
|
|
newDT = document.createElement("dt"), |
|
671
|
|
|
newInput = document.createElement("input"), |
|
672
|
|
|
newLabel = document.createElement("label"), |
|
673
|
|
|
newDD = document.createElement("dd"); |
|
674
|
|
|
|
|
675
|
|
|
newInput.name = "engine_name[]"; |
|
676
|
|
|
newInput.type = "text"; |
|
677
|
|
|
newInput.className = "input_text"; |
|
678
|
|
|
newInput.size = "50"; |
|
679
|
|
|
newInput.setAttribute("class", "verification_question"); |
|
680
|
|
|
|
|
681
|
|
|
// Add the label and input box to the DOM |
|
682
|
|
|
newLabel.textContent = txt_name + ': '; |
|
683
|
|
|
newLabel.appendChild(newInput); |
|
684
|
|
|
newDT.appendChild(newLabel); |
|
685
|
|
|
|
|
686
|
|
|
// Next input box |
|
687
|
|
|
newInput = document.createElement("input"); |
|
688
|
|
|
newInput.name = "engine_url[]"; |
|
689
|
|
|
newInput.type = "text"; |
|
690
|
|
|
newInput.className = "input_text"; |
|
691
|
|
|
newInput.size = "35"; |
|
692
|
|
|
newInput.setAttribute("class", "input_text verification_answer"); |
|
693
|
|
|
|
|
694
|
|
|
// Add the new label and input box |
|
695
|
|
|
newLabel = document.createElement("label"); |
|
696
|
|
|
newLabel.textContent = txt_url + ': '; |
|
697
|
|
|
newLabel.appendChild(newInput); |
|
698
|
|
|
newDD.appendChild(newLabel); |
|
699
|
|
|
newDD.appendChild(document.createElement("br")); |
|
700
|
|
|
|
|
701
|
|
|
// Rinse and repeat |
|
702
|
|
|
newInput = document.createElement("input"); |
|
703
|
|
|
newInput.name = "engine_separator[]"; |
|
704
|
|
|
newInput.type = "text"; |
|
705
|
|
|
newInput.className = "input_text"; |
|
706
|
|
|
newInput.size = "5"; |
|
707
|
|
|
newInput.setAttribute("class", "input_text verification_answer"); |
|
708
|
|
|
|
|
709
|
|
|
newLabel = document.createElement("label"); |
|
710
|
|
|
newLabel.textContent = txt_word_sep + ': '; |
|
711
|
|
|
newLabel.appendChild(newInput); |
|
712
|
|
|
newDD.appendChild(newLabel); |
|
713
|
|
|
|
|
714
|
|
|
placeHolder.parentNode.insertBefore(newDT, placeHolder); |
|
715
|
|
|
placeHolder.parentNode.insertBefore(newDD, placeHolder); |
|
716
|
|
|
} |
|
717
|
|
|
|
|
718
|
|
|
/** |
|
719
|
|
|
* News admin page |
|
720
|
|
|
*/ |
|
721
|
|
|
function addAnotherNews() |
|
722
|
|
|
{ |
|
723
|
|
|
var last = $("#list_news_lists_last"), |
|
724
|
|
|
$new_item = last.clone(); |
|
725
|
|
|
|
|
726
|
|
|
last_preview++; |
|
727
|
|
|
$new_item.attr('id', 'list_news_lists_' + last_preview); |
|
728
|
|
|
$new_item.find('textarea').attr('id', 'data_' + last_preview); |
|
729
|
|
|
$new_item.find('#preview_last').attr('id', 'preview_' + last_preview); |
|
730
|
|
|
$new_item.find('#box_preview_last').attr('id', 'box_preview_' + last_preview); |
|
731
|
|
|
|
|
732
|
|
|
last.before($new_item); |
|
733
|
|
|
$new_item.toggle(); |
|
734
|
|
|
make_preview_btn(last_preview); |
|
735
|
|
|
} |
|
736
|
|
|
|
|
737
|
|
|
/** |
|
738
|
|
|
* Makes the preview button when in manage news |
|
739
|
|
|
* |
|
740
|
|
|
* @param {string} preview_id |
|
741
|
|
|
*/ |
|
742
|
|
|
function make_preview_btn (preview_id) |
|
743
|
|
|
{ |
|
744
|
|
|
var $id = $("#preview_" + preview_id); |
|
745
|
|
|
|
|
746
|
|
|
$id.text(txt_preview).on('click', function () { |
|
747
|
|
|
$.ajax({ |
|
748
|
|
|
type: "POST", |
|
749
|
|
|
url: elk_scripturl + "?action=xmlpreview;xml", |
|
750
|
|
|
data: {item: "newspreview", news: $("#data_" + preview_id).val()}, |
|
751
|
|
|
context: document.body |
|
752
|
|
|
}) |
|
753
|
|
|
.done(function(request) { |
|
754
|
|
|
if ($(request).find("error").text() === '') |
|
755
|
|
|
$(document).find("#box_preview_" + preview_id).html($(request).text()); |
|
|
|
|
|
|
756
|
|
|
else |
|
757
|
|
|
$(document).find("#box_preview_" + preview_id).text(txt_news_error_no_news); |
|
758
|
|
|
}); |
|
759
|
|
|
}); |
|
760
|
|
|
|
|
761
|
|
|
if (!$id.parent().hasClass('linkbutton_right')) |
|
762
|
|
|
$id.wrap('<a class="linkbutton_right" href="javascript:void(0);"></a>'); |
|
|
|
|
|
|
763
|
|
|
} |
|
764
|
|
|
|
|
765
|
|
|
/** |
|
766
|
|
|
* Used by manage themes to show the thumbnail of the theme variant chosen |
|
767
|
|
|
* |
|
768
|
|
|
* @param {string} sVariant |
|
769
|
|
|
*/ |
|
770
|
|
|
function changeVariant(sVariant) |
|
771
|
|
|
{ |
|
772
|
|
|
document.getElementById('variant_preview').src = oThumbnails[sVariant]; |
|
773
|
|
|
} |
|
774
|
|
|
|
|
775
|
|
|
/** |
|
776
|
|
|
* The idea here is simple: don't refresh the preview on every keypress, but do refresh after they type. |
|
777
|
|
|
* |
|
778
|
|
|
* @returns {undefined} |
|
779
|
|
|
*/ |
|
780
|
|
|
function setPreviewTimeout() |
|
781
|
|
|
{ |
|
782
|
|
|
if (previewTimeout) |
|
783
|
|
|
{ |
|
784
|
|
|
window.clearTimeout(previewTimeout); |
|
785
|
|
|
previewTimeout = null; |
|
786
|
|
|
} |
|
787
|
|
|
|
|
788
|
|
|
previewTimeout = window.setTimeout(function() {refreshPreview(true); previewTimeout = null;}, 500); |
|
789
|
|
|
} |
|
790
|
|
|
|
|
791
|
|
|
/** |
|
792
|
|
|
* Used in manage paid subscriptions to show the fixed duration panel or |
|
793
|
|
|
* the variable duration panel, based on which radio button is selected |
|
794
|
|
|
* |
|
795
|
|
|
* @param {type} toChange |
|
796
|
|
|
*/ |
|
797
|
|
|
function toggleDuration(toChange) |
|
|
|
|
|
|
798
|
|
|
{ |
|
799
|
|
|
$("#fixed_area").slideToggle(300); |
|
800
|
|
|
$("#flexible_area").slideToggle(300); |
|
801
|
|
|
} |
|
802
|
|
|
|
|
803
|
|
|
/** |
|
804
|
|
|
* Used when editing the search weights for results, calculates the overall total weight |
|
805
|
|
|
*/ |
|
806
|
|
|
function calculateNewValues() |
|
807
|
|
|
{ |
|
808
|
|
|
var total = 0; |
|
809
|
|
|
for (var i = 1; i <= 7; i++) |
|
810
|
|
|
{ |
|
811
|
|
|
total += parseInt(document.getElementById('weight' + i + '_val').value); |
|
812
|
|
|
} |
|
813
|
|
|
|
|
814
|
|
|
document.getElementById('weighttotal').innerHTML = total; |
|
815
|
|
|
for (i = 1; i <= 7; i++) |
|
816
|
|
|
{ |
|
817
|
|
|
document.getElementById('weight' + i).innerHTML = (Math.round(1000 * parseInt(document.getElementById('weight' + i + '_val').value) / total) / 10) + '%'; |
|
818
|
|
|
} |
|
819
|
|
|
} |
|
820
|
|
|
|
|
821
|
|
|
/** |
|
822
|
|
|
* Toggle visibility of add smile image source options |
|
823
|
|
|
*/ |
|
824
|
|
|
function switchType() |
|
825
|
|
|
{ |
|
826
|
|
|
document.getElementById("ul_settings").style.display = document.getElementById("method-existing").checked ? "none" : "block"; |
|
827
|
|
|
document.getElementById("ex_settings").style.display = document.getElementById("method-upload").checked ? "none" : "block"; |
|
828
|
|
|
} |
|
829
|
|
|
|
|
830
|
|
|
/** |
|
831
|
|
|
* Toggle visibility of smiley set should the user want different images in a set (add smiley) |
|
832
|
|
|
*/ |
|
833
|
|
|
function swapUploads() |
|
834
|
|
|
{ |
|
835
|
|
|
document.getElementById("uploadMore").style.display = document.getElementById("uploadSmiley").disabled ? "none" : "block"; |
|
836
|
|
|
document.getElementById("uploadSmiley").disabled = !document.getElementById("uploadSmiley").disabled; |
|
837
|
|
|
} |
|
838
|
|
|
|
|
839
|
|
|
/** |
|
840
|
|
|
* Close the options that should not be visible for adding a smiley |
|
841
|
|
|
* |
|
842
|
|
|
* @param {string} element |
|
843
|
|
|
*/ |
|
844
|
|
|
function selectMethod(element) |
|
845
|
|
|
{ |
|
846
|
|
|
document.getElementById("method-existing").checked = element !== "upload"; |
|
847
|
|
|
document.getElementById("method-upload").checked = element === "upload"; |
|
848
|
|
|
} |
|
849
|
|
|
|
|
850
|
|
|
/** |
|
851
|
|
|
* Updates the smiley preview to show the current one chosen |
|
852
|
|
|
*/ |
|
853
|
|
|
function updatePreview() |
|
854
|
|
|
{ |
|
855
|
|
|
var currentImage = document.getElementById("preview"); |
|
856
|
|
|
currentImage.src = elk_smiley_url + "/" + document.forms.smileyForm.set.value + "/" + document.forms.smileyForm.smiley_filename.value; |
|
857
|
|
|
} |
|
858
|
|
|
|
|
859
|
|
|
/** |
|
860
|
|
|
* Used in package manager to swap the visibility of database changes |
|
861
|
|
|
*/ |
|
862
|
|
|
function swap_database_changes() |
|
863
|
|
|
{ |
|
864
|
|
|
db_vis = !db_vis; |
|
865
|
|
|
database_changes_area.style.display = db_vis ? "" : "none"; |
|
866
|
|
|
|
|
867
|
|
|
return false; |
|
868
|
|
|
} |
|
869
|
|
|
|
|
870
|
|
|
/** |
|
871
|
|
|
* Test the given form credentials to test if an FTP connection can be made |
|
872
|
|
|
*/ |
|
873
|
|
|
function testFTP() |
|
874
|
|
|
{ |
|
875
|
|
|
ajax_indicator(true); |
|
876
|
|
|
|
|
877
|
|
|
// What we need to post. |
|
878
|
|
|
var oPostData = { |
|
879
|
|
|
0: "ftp_server", |
|
880
|
|
|
1: "ftp_port", |
|
881
|
|
|
2: "ftp_username", |
|
882
|
|
|
3: "ftp_password", |
|
883
|
|
|
4: "ftp_path" |
|
884
|
|
|
}; |
|
885
|
|
|
|
|
886
|
|
|
var sPostData = ""; |
|
887
|
|
|
for (var i = 0; i < 5; i++) |
|
888
|
|
|
sPostData = sPostData + (sPostData.length === 0 ? "" : "&") + oPostData[i] + "=" + document.getElementById(oPostData[i]).value.php_urlencode(); |
|
|
|
|
|
|
889
|
|
|
|
|
890
|
|
|
// Post the data out. |
|
891
|
|
|
sendXMLDocument(elk_prepareScriptUrl(elk_scripturl) + 'action=admin;area=packages;sa=ftptest;xml;' + elk_session_var + '=' + elk_session_id, sPostData, testFTPResults); |
|
892
|
|
|
} |
|
893
|
|
|
|
|
894
|
|
|
/** |
|
895
|
|
|
* Generate a "test ftp" button. |
|
896
|
|
|
*/ |
|
897
|
|
|
function generateFTPTest() |
|
898
|
|
|
{ |
|
899
|
|
|
// Don't ever call this twice! |
|
900
|
|
|
if (generatedButton) |
|
|
|
|
|
|
901
|
|
|
return false; |
|
|
|
|
|
|
902
|
|
|
|
|
903
|
|
|
generatedButton = true; |
|
|
|
|
|
|
904
|
|
|
|
|
905
|
|
|
// No XML? |
|
906
|
|
|
if (!document.getElementById("test_ftp_placeholder") && !document.getElementById("test_ftp_placeholder_full")) |
|
907
|
|
|
return false; |
|
|
|
|
|
|
908
|
|
|
|
|
909
|
|
|
// create our test button to call testFTP on click |
|
910
|
|
|
var ftpTest = document.createElement("input"); |
|
911
|
|
|
ftpTest.type = "button"; |
|
912
|
|
|
ftpTest.className = "submit"; |
|
913
|
|
|
ftpTest.onclick = testFTP; |
|
914
|
|
|
|
|
915
|
|
|
// Set the button value based on which form we are on |
|
916
|
|
|
if (document.getElementById("test_ftp_placeholder")) |
|
917
|
|
|
{ |
|
918
|
|
|
ftpTest.value = package_ftp_test; |
|
919
|
|
|
document.getElementById("test_ftp_placeholder").appendChild(ftpTest); |
|
920
|
|
|
} |
|
921
|
|
|
else |
|
922
|
|
|
{ |
|
923
|
|
|
ftpTest.value = package_ftp_test_connection; |
|
924
|
|
|
document.getElementById("test_ftp_placeholder_full").appendChild(ftpTest); |
|
925
|
|
|
} |
|
926
|
|
|
|
|
927
|
|
|
return true; |
|
928
|
|
|
} |
|
929
|
|
|
|
|
930
|
|
|
/** |
|
931
|
|
|
* Callback function of the testFTP function |
|
932
|
|
|
* |
|
933
|
|
|
* @param {type} oXMLDoc |
|
934
|
|
|
*/ |
|
935
|
|
|
function testFTPResults(oXMLDoc) |
|
936
|
|
|
{ |
|
937
|
|
|
ajax_indicator(false); |
|
938
|
|
|
|
|
939
|
|
|
// This assumes it went wrong! |
|
940
|
|
|
var wasSuccess = false, |
|
941
|
|
|
message = package_ftp_test_failed, |
|
942
|
|
|
results = oXMLDoc.getElementsByTagName('results')[0].getElementsByTagName('result'); |
|
943
|
|
|
|
|
944
|
|
|
// Results show we were a success |
|
945
|
|
|
if (results.length > 0) |
|
946
|
|
|
{ |
|
947
|
|
|
if (parseInt(results[0].getAttribute('success')) === 1) |
|
948
|
|
|
wasSuccess = true; |
|
|
|
|
|
|
949
|
|
|
message = results[0].firstChild.nodeValue; |
|
950
|
|
|
} |
|
951
|
|
|
|
|
952
|
|
|
// place the informative box on screen so the user knows if things went well or poorly |
|
953
|
|
|
document.getElementById("ftp_error_div").style.display = ""; |
|
954
|
|
|
document.getElementById("ftp_error_div").className = wasSuccess ? "successbox" : "errorbox"; |
|
955
|
|
|
document.getElementById("ftp_error_message").innerHTML = message; |
|
956
|
|
|
} |
|
957
|
|
|
|
|
958
|
|
|
/** |
|
959
|
|
|
* Part of package manager, expands a folders contents to show |
|
960
|
|
|
* permission levels of files it contains. |
|
961
|
|
|
* Will use an ajax call to get any permissions it has not loaded |
|
962
|
|
|
* |
|
963
|
|
|
* @param {type} folderIdent |
|
964
|
|
|
* @param {type} folderReal |
|
965
|
|
|
*/ |
|
966
|
|
|
function expandFolder(folderIdent, folderReal) |
|
967
|
|
|
{ |
|
968
|
|
|
// See if it already exists. |
|
969
|
|
|
var possibleTags = document.getElementsByTagName("tr"); |
|
970
|
|
|
var foundOne = false; |
|
971
|
|
|
|
|
972
|
|
|
for (var i = 0; i < possibleTags.length; i++) |
|
973
|
|
|
{ |
|
974
|
|
|
if (possibleTags[i].id.indexOf("content_" + folderIdent + ":-:") === 0) |
|
975
|
|
|
{ |
|
976
|
|
|
possibleTags[i].style.display = possibleTags[i].style.display === "none" ? "" : "none"; |
|
977
|
|
|
foundOne = true; |
|
978
|
|
|
} |
|
979
|
|
|
} |
|
980
|
|
|
|
|
981
|
|
|
// Got something then we're done. |
|
982
|
|
|
if (foundOne) |
|
983
|
|
|
{ |
|
984
|
|
|
return false; |
|
985
|
|
|
} |
|
986
|
|
|
|
|
987
|
|
|
// Otherwise we need to get the wicked thing. |
|
988
|
|
|
ajax_indicator(true); |
|
989
|
|
|
getXMLDocument(elk_prepareScriptUrl(elk_scripturl) + 'action=admin;area=packages;onlyfind=' + folderReal.php_urlencode() + ';sa=perms;xml;' + elk_session_var + '=' + elk_session_id, onNewFolderReceived); |
|
990
|
|
|
|
|
991
|
|
|
return false; |
|
992
|
|
|
} |
|
993
|
|
|
|
|
994
|
|
|
/** |
|
995
|
|
|
* Wrapper function to call expandFolder |
|
996
|
|
|
*/ |
|
997
|
|
|
function dynamicExpandFolder() |
|
998
|
|
|
{ |
|
999
|
|
|
expandFolder(this.ident, this.path); |
|
1000
|
|
|
|
|
1001
|
|
|
return false; |
|
1002
|
|
|
} |
|
1003
|
|
|
|
|
1004
|
|
|
/** |
|
1005
|
|
|
* Used when edit the boards and groups access to them |
|
1006
|
|
|
* |
|
1007
|
|
|
* @param {type} operation |
|
1008
|
|
|
* @param {type} brd_list |
|
1009
|
|
|
*/ |
|
1010
|
|
|
function select_in_category(operation, brd_list) |
|
1011
|
|
|
{ |
|
1012
|
|
|
for (var brd in brd_list) { |
|
1013
|
|
|
if (!brd_list.hasOwnProperty(brd)) |
|
1014
|
|
|
continue; |
|
|
|
|
|
|
1015
|
|
|
|
|
1016
|
|
|
document.getElementById(operation + '_brd' + brd_list[brd]).checked = true; |
|
1017
|
|
|
} |
|
1018
|
|
|
} |
|
1019
|
|
|
|
|
1020
|
|
|
/** |
|
1021
|
|
|
* Server Settings > Caching, toggles input fields on/off as appropriate for |
|
1022
|
|
|
* a given cache engine selection |
|
1023
|
|
|
*/ |
|
1024
|
|
|
$(function() { |
|
1025
|
|
|
$('#cache_accelerator').change(function() { |
|
1026
|
|
|
// Hide all the settings |
|
1027
|
|
|
$('#cache_accelerator').find('option').each(function() { |
|
1028
|
|
|
$('[id^=' + $(this).val() + '_]').hide(); |
|
1029
|
|
|
}); |
|
1030
|
|
|
|
|
1031
|
|
|
// Show the settings of the selected engine |
|
1032
|
|
|
$('[id^=' + $(this).val() + '_]').show(); |
|
1033
|
|
|
}) |
|
1034
|
|
|
// Trigger a change action so that the form is properly initialized |
|
1035
|
|
|
.change(); |
|
1036
|
|
|
}); |
|
1037
|
|
|
|
|
1038
|
|
|
/** |
|
1039
|
|
|
* Server Settings > Caching, toggles input fields on/off as appropriate for |
|
1040
|
|
|
* a given cache engine selection |
|
1041
|
|
|
*/ |
|
1042
|
|
|
function toggleCache () |
|
1043
|
|
|
{ |
|
1044
|
|
|
var memcache = $('#cache_memcached').parent(), |
|
1045
|
|
|
cachedir = $('#cachedir').parent(), |
|
1046
|
|
|
cacheuid = $('#cache_uid').parent(), |
|
1047
|
|
|
cachepassword = $('#cache_password').parent(), |
|
1048
|
|
|
cacheconfirm = $('#cache_password_confirm').parent(); |
|
1049
|
|
|
|
|
1050
|
|
|
// Show the memcache server box only if memcache has been selected |
|
1051
|
|
|
if (cache_type.value.substr(0, 8) !== "memcache") |
|
|
|
|
|
|
1052
|
|
|
{ |
|
1053
|
|
|
memcache.slideUp(); |
|
1054
|
|
|
memcache.prev().slideUp(100); |
|
1055
|
|
|
} |
|
1056
|
|
|
else |
|
1057
|
|
|
{ |
|
1058
|
|
|
memcache.slideDown(); |
|
1059
|
|
|
memcache.prev().slideDown(100); |
|
1060
|
|
|
} |
|
1061
|
|
|
|
|
1062
|
|
|
// don't show the directory if its not filebased |
|
1063
|
|
|
if (cache_type.value === "filebased") |
|
1064
|
|
|
{ |
|
1065
|
|
|
cachedir.slideDown(); |
|
1066
|
|
|
cachedir.prev().slideDown(100); |
|
1067
|
|
|
} |
|
1068
|
|
|
else |
|
1069
|
|
|
{ |
|
1070
|
|
|
cachedir.slideUp(100); |
|
1071
|
|
|
cachedir.prev().slideUp(100); |
|
1072
|
|
|
} |
|
1073
|
|
|
|
|
1074
|
|
|
// right now only xcache needs the uid/password |
|
1075
|
|
|
if (cache_type.value === "xcache") |
|
1076
|
|
|
{ |
|
1077
|
|
|
cacheuid.slideDown(100); |
|
1078
|
|
|
cacheuid.prev().slideDown(100); |
|
1079
|
|
|
cachepassword.slideDown(100); |
|
1080
|
|
|
cachepassword.prev().slideDown(100); |
|
1081
|
|
|
cacheconfirm.slideDown(100); |
|
1082
|
|
|
cacheconfirm.prev().slideDown(100); |
|
1083
|
|
|
} |
|
1084
|
|
|
else |
|
1085
|
|
|
{ |
|
1086
|
|
|
cacheuid.slideUp(100); |
|
1087
|
|
|
cacheuid.prev().slideUp(100); |
|
1088
|
|
|
cachepassword.slideUp(100); |
|
1089
|
|
|
cachepassword.prev().slideUp(100); |
|
1090
|
|
|
cacheconfirm.slideUp(100); |
|
1091
|
|
|
cacheconfirm.prev().slideUp(100); |
|
1092
|
|
|
} |
|
1093
|
|
|
} |
|
1094
|
|
|
|
|
1095
|
|
|
/** |
|
1096
|
|
|
* Hides local / subdomain cookie options in the ACP based on selected choices |
|
1097
|
|
|
* area=serversettings;sa=cookie |
|
1098
|
|
|
*/ |
|
1099
|
|
|
function hideGlobalCookies() |
|
1100
|
|
|
{ |
|
1101
|
|
|
var bUseLocal = document.getElementById("localCookies").checked, |
|
1102
|
|
|
bUseGlobal = !bUseLocal && document.getElementById("globalCookies").checked; |
|
1103
|
|
|
|
|
1104
|
|
|
// Show/Hide the areas based on what they have chosen |
|
1105
|
|
|
if (!bUseLocal) |
|
1106
|
|
|
{ |
|
1107
|
|
|
$("#setting_globalCookies").parent().slideDown(); |
|
1108
|
|
|
$("#globalCookies").parent().slideDown(); |
|
1109
|
|
|
} |
|
1110
|
|
|
else |
|
1111
|
|
|
{ |
|
1112
|
|
|
$("#setting_globalCookies").parent().slideUp(); |
|
1113
|
|
|
$("#globalCookies").parent().slideUp(); |
|
1114
|
|
|
} |
|
1115
|
|
|
|
|
1116
|
|
|
// Global selected means we need to reveal the domain input box |
|
1117
|
|
|
if (bUseGlobal) |
|
1118
|
|
|
{ |
|
1119
|
|
|
$("#setting_globalCookiesDomain").closest("dt").slideDown(); |
|
1120
|
|
|
$("#globalCookiesDomain").closest("dd").slideDown(); |
|
1121
|
|
|
} |
|
1122
|
|
|
else |
|
1123
|
|
|
{ |
|
1124
|
|
|
$("#setting_globalCookiesDomain").closest("dt").slideUp(); |
|
1125
|
|
|
$("#globalCookiesDomain").closest("dd").slideUp(); |
|
1126
|
|
|
} |
|
1127
|
|
|
} |
|
1128
|
|
|
|
|
1129
|
|
|
/** |
|
1130
|
|
|
* Attachments Settings |
|
1131
|
|
|
*/ |
|
1132
|
|
|
function toggleSubDir () |
|
1133
|
|
|
{ |
|
1134
|
|
|
var auto_attach = document.getElementById('automanage_attachments'), |
|
1135
|
|
|
use_sub_dir = document.getElementById('use_subdirectories_for_attachments'), |
|
1136
|
|
|
dir_elem = document.getElementById('basedirectory_for_attachments'); |
|
1137
|
|
|
|
|
1138
|
|
|
use_sub_dir.disabled = !Boolean(auto_attach.selectedIndex); |
|
1139
|
|
|
if (use_sub_dir.disabled) |
|
1140
|
|
|
{ |
|
1141
|
|
|
$(use_sub_dir).slideUp(); |
|
1142
|
|
|
$('#setting_use_subdirectories_for_attachments').parent().slideUp(); |
|
1143
|
|
|
|
|
1144
|
|
|
$(dir_elem).slideUp(); |
|
1145
|
|
|
$('#setting_basedirectory_for_attachments').parent().slideUp(); |
|
1146
|
|
|
} |
|
1147
|
|
|
else |
|
1148
|
|
|
{ |
|
1149
|
|
|
$(use_sub_dir).slideDown(); |
|
1150
|
|
|
$('#setting_use_subdirectories_for_attachments').parent().slideDown(); |
|
1151
|
|
|
|
|
1152
|
|
|
$(dir_elem).slideDown(); |
|
1153
|
|
|
$('#setting_basedirectory_for_attachments').parent().slideDown(); |
|
1154
|
|
|
} |
|
1155
|
|
|
toggleBaseDir(); |
|
1156
|
|
|
} |
|
1157
|
|
|
|
|
1158
|
|
|
/** |
|
1159
|
|
|
* Called by toggleSubDir as part of manage attachments |
|
1160
|
|
|
*/ |
|
1161
|
|
|
function toggleBaseDir () |
|
1162
|
|
|
{ |
|
1163
|
|
|
var auto_attach = document.getElementById('automanage_attachments'), |
|
1164
|
|
|
sub_dir = document.getElementById('use_subdirectories_for_attachments'), |
|
1165
|
|
|
dir_elem = document.getElementById('basedirectory_for_attachments'); |
|
1166
|
|
|
|
|
1167
|
|
|
if (auto_attach.selectedIndex === 0) |
|
1168
|
|
|
dir_elem.disabled = 1; |
|
|
|
|
|
|
1169
|
|
|
else |
|
1170
|
|
|
dir_elem.disabled = !sub_dir.checked; |
|
1171
|
|
|
} |
|
1172
|
|
|
|
|
1173
|
|
|
|
|
1174
|
|
|
/** |
|
1175
|
|
|
* Called from purgeinactive users maintenance task, used to show or hide |
|
1176
|
|
|
* the membergroup list. If collapsed will select all the member groups if expanded |
|
1177
|
|
|
* unselect them so the user can choose. |
|
1178
|
|
|
*/ |
|
1179
|
|
|
function swapMembers() |
|
1180
|
|
|
{ |
|
1181
|
|
|
var membersForm = document.getElementById('membersForm'); |
|
1182
|
|
|
|
|
1183
|
|
|
// Make it close smoothly |
|
1184
|
|
|
$("#membersPanel").slideToggle(300); |
|
1185
|
|
|
|
|
1186
|
|
|
membersSwap = !membersSwap; |
|
1187
|
|
|
document.getElementById("membersIcon").src = elk_images_url + (membersSwap ? "/selected_open.png" : "/selected.png"); |
|
1188
|
|
|
document.getElementById("membersText").innerHTML = membersSwap ? maintain_members_choose : maintain_members_all; |
|
1189
|
|
|
|
|
1190
|
|
|
// Check or uncheck them all based on if we are expanding or collasping the area |
|
1191
|
|
|
for (var i = 0; i < membersForm.length; i++) |
|
1192
|
|
|
{ |
|
1193
|
|
|
if (membersForm.elements[i].type.toLowerCase() === "checkbox") |
|
1194
|
|
|
membersForm.elements[i].checked = !membersSwap; |
|
|
|
|
|
|
1195
|
|
|
} |
|
1196
|
|
|
|
|
1197
|
|
|
return false; |
|
1198
|
|
|
} |
|
1199
|
|
|
|
|
1200
|
|
|
/** |
|
1201
|
|
|
* Called from reattribute member posts to build the confirm message for the action |
|
1202
|
|
|
* Keeps the action button (reattribute) disabled until all necessary fields have been filled |
|
1203
|
|
|
*/ |
|
1204
|
|
|
function checkAttributeValidity() |
|
1205
|
|
|
{ |
|
1206
|
|
|
origText = reattribute_confirm; |
|
1207
|
|
|
valid = true; |
|
1208
|
|
|
|
|
1209
|
|
|
// Do all the fields! |
|
1210
|
|
|
if (!document.getElementById('to').value) |
|
1211
|
|
|
valid = false; |
|
|
|
|
|
|
1212
|
|
|
|
|
1213
|
|
|
warningMessage = origText.replace(/%member_to%/, document.getElementById('to').value); |
|
1214
|
|
|
|
|
1215
|
|
|
// Using email address to find the member |
|
1216
|
|
|
if (document.getElementById('type_email').checked) |
|
1217
|
|
|
{ |
|
1218
|
|
|
if (!document.getElementById('from_email').value) |
|
1219
|
|
|
valid = false; |
|
|
|
|
|
|
1220
|
|
|
|
|
1221
|
|
|
warningMessage = warningMessage.replace(/%type%/, '', reattribute_confirm_email).replace(/%find%/, document.getElementById('from_email').value); |
|
1222
|
|
|
} |
|
1223
|
|
|
// Or the user name |
|
1224
|
|
|
else |
|
1225
|
|
|
{ |
|
1226
|
|
|
if (!document.getElementById('from_name').value) |
|
1227
|
|
|
valid = false; |
|
|
|
|
|
|
1228
|
|
|
|
|
1229
|
|
|
warningMessage = warningMessage.replace(/%type%/, '', reattribute_confirm_username).replace(/%find%/, document.getElementById('from_name').value); |
|
1230
|
|
|
} |
|
1231
|
|
|
|
|
1232
|
|
|
document.getElementById('do_attribute').disabled = !valid; |
|
1233
|
|
|
|
|
1234
|
|
|
// Keep checking for a valid form so we can activate the submit button |
|
1235
|
|
|
setTimeout(function() {checkAttributeValidity();}, 500); |
|
1236
|
|
|
|
|
1237
|
|
|
return valid; |
|
1238
|
|
|
} |
|
1239
|
|
|
|
|
1240
|
|
|
/** |
|
1241
|
|
|
* Enable/disable fields when transferring attachments |
|
1242
|
|
|
* |
|
1243
|
|
|
* @returns {undefined} |
|
1244
|
|
|
*/ |
|
1245
|
|
|
function transferAttachOptions() |
|
1246
|
|
|
{ |
|
1247
|
|
|
var autoSelect = document.getElementById("auto"), |
|
1248
|
|
|
autoValue = parseInt(autoSelect.options[autoSelect.selectedIndex].value, 10), |
|
1249
|
|
|
toSelect = document.getElementById("to"), |
|
1250
|
|
|
toValue = parseInt(toSelect.options[toSelect.selectedIndex].value, 10); |
|
1251
|
|
|
|
|
1252
|
|
|
toSelect.disabled = autoValue !== 0; |
|
1253
|
|
|
autoSelect.disabled = toValue !== 0; |
|
1254
|
|
|
} |
|
1255
|
|
|
|
|
1256
|
|
|
/** |
|
1257
|
|
|
* Updates the move confirmation text so its descriptive for the current items |
|
1258
|
|
|
* being moved. |
|
1259
|
|
|
* |
|
1260
|
|
|
* @param {string} confirmText |
|
1261
|
|
|
*/ |
|
1262
|
|
|
function confirmMoveTopics(confirmText) |
|
1263
|
|
|
{ |
|
1264
|
|
|
var from = document.getElementById('id_board_from'), |
|
1265
|
|
|
to = document.getElementById('id_board_to'); |
|
1266
|
|
|
|
|
1267
|
|
|
if (from.options[from.selectedIndex].disabled || from.options[to.selectedIndex].disabled) |
|
1268
|
|
|
return false; |
|
|
|
|
|
|
1269
|
|
|
|
|
1270
|
|
|
return confirm(confirmText.replace(/%board_from%/, from.options[from.selectedIndex].text.replace(/^\u2003+\u27A4/, '')).replace(/%board_to%/, to.options[to.selectedIndex].text.replace(/^\u2003+\u27A4/, ''))); |
|
|
|
|
|
|
1271
|
|
|
} |
|
1272
|
|
|
|
|
1273
|
|
|
/** |
|
1274
|
|
|
* Hide the search methods area if using sphinx(ql) search |
|
1275
|
|
|
*/ |
|
1276
|
|
|
function showhideSearchMethod() |
|
1277
|
|
|
{ |
|
1278
|
|
|
var searchSphinxQl = document.getElementById('search_index_sphinxql').checked, |
|
1279
|
|
|
searchSphinx = document.getElementById('search_index_sphinx').checked, |
|
1280
|
|
|
searchhide = searchSphinxQl || searchSphinx, |
|
1281
|
|
|
searchMethod = $('#search_method'); |
|
1282
|
|
|
|
|
1283
|
|
|
if (searchhide) |
|
1284
|
|
|
searchMethod.slideUp(); |
|
|
|
|
|
|
1285
|
|
|
else |
|
1286
|
|
|
searchMethod.slideDown(); |
|
1287
|
|
|
} |
|
1288
|
|
|
|
|
1289
|
|
|
/** |
|
1290
|
|
|
* Used in manageFeatures to show / hide custom level input elements based on the checkbox choices |
|
1291
|
|
|
* Will show or hide the jquery and jqueryui custom input fields for admins that like to roll the dice |
|
1292
|
|
|
*/ |
|
1293
|
|
|
function showhideJqueryOptions() |
|
1294
|
|
|
{ |
|
1295
|
|
|
var jqBase = document.getElementById('jquery_default').checked, |
|
1296
|
|
|
jqUi = document.getElementById('jqueryui_default').checked, |
|
1297
|
|
|
jqBase_val = $('#jquery_version'), |
|
1298
|
|
|
jqUi_val = $('#jqueryui_version'); |
|
1299
|
|
|
|
|
1300
|
|
|
// Show the jquery custom level box only if the option has been selected |
|
1301
|
|
|
// yes the dt dd stuff makes it this ugly |
|
1302
|
|
|
if (jqBase === false) |
|
1303
|
|
|
{ |
|
1304
|
|
|
// dd and the dt |
|
1305
|
|
|
jqBase_val.parent().slideUp(); |
|
1306
|
|
|
jqBase_val.parent().prev().slideUp(); |
|
1307
|
|
|
} |
|
1308
|
|
|
else |
|
1309
|
|
|
{ |
|
1310
|
|
|
jqBase_val.parent().slideDown(); |
|
1311
|
|
|
jqBase_val.parent().prev().slideDown(); |
|
1312
|
|
|
} |
|
1313
|
|
|
|
|
1314
|
|
|
// And the same for the UI areas as well |
|
1315
|
|
|
if (jqUi === false) |
|
1316
|
|
|
{ |
|
1317
|
|
|
// The parent is the dd and the sibling is its dt |
|
1318
|
|
|
jqUi_val.parent().slideUp(); |
|
1319
|
|
|
jqUi_val.parent().prev().slideUp(); |
|
1320
|
|
|
} |
|
1321
|
|
|
else |
|
1322
|
|
|
{ |
|
1323
|
|
|
jqUi_val.parent().slideDown(); |
|
1324
|
|
|
jqUi_val.parent().prev().slideDown(); |
|
1325
|
|
|
} |
|
1326
|
|
|
} |
|
1327
|
|
|
|
|
1328
|
|
|
/** |
|
1329
|
|
|
* Used in manageMembergroups to enable disable form elements based on allowable choices |
|
1330
|
|
|
* If post based group is selected, it will disable moderation selection, visibility, group description |
|
1331
|
|
|
* and enable post count input box |
|
1332
|
|
|
* |
|
1333
|
|
|
* @param {boolean} isChecked |
|
1334
|
|
|
*/ |
|
1335
|
|
|
function swapPostGroup(isChecked) |
|
1336
|
|
|
{ |
|
1337
|
|
|
var min_posts_text = document.getElementById('min_posts_text'), |
|
1338
|
|
|
group_desc_text = document.getElementById('group_desc_text'), |
|
1339
|
|
|
group_hidden_text = document.getElementById('group_hidden_text'), |
|
1340
|
|
|
group_moderators_text = document.getElementById('group_moderators_text'); |
|
1341
|
|
|
|
|
1342
|
|
|
document.forms.groupForm.min_posts.disabled = !isChecked; |
|
1343
|
|
|
min_posts_text.style.color = isChecked ? "" : "#888"; |
|
1344
|
|
|
|
|
1345
|
|
|
document.forms.groupForm.group_desc_input.disabled = isChecked; |
|
1346
|
|
|
group_desc_text.style.color = !isChecked ? "" : "#888"; |
|
1347
|
|
|
|
|
1348
|
|
|
document.forms.groupForm.group_hidden_input.disabled = isChecked; |
|
1349
|
|
|
group_hidden_text.style.color = !isChecked ? "" : "#888"; |
|
1350
|
|
|
|
|
1351
|
|
|
document.forms.groupForm.group_moderators.disabled = isChecked; |
|
1352
|
|
|
group_moderators_text.style.color = !isChecked ? "" : "#888"; |
|
1353
|
|
|
|
|
1354
|
|
|
// Disable the moderator autosuggest box as well |
|
1355
|
|
|
if (typeof(oModeratorSuggest) !== 'undefined') |
|
1356
|
|
|
oModeratorSuggest.oTextHandle.disabled = !!isChecked; |
|
|
|
|
|
|
1357
|
|
|
} |
|
1358
|
|
|
|
|
1359
|
|
|
/** |
|
1360
|
|
|
* Handles the AJAX preview of the warning templates |
|
1361
|
|
|
*/ |
|
1362
|
|
|
function ajax_getTemplatePreview() |
|
1363
|
|
|
{ |
|
1364
|
|
|
$.ajax({ |
|
1365
|
|
|
type: "POST", |
|
1366
|
|
|
url: elk_scripturl + '?action=xmlpreview;xml', |
|
1367
|
|
|
data: { |
|
1368
|
|
|
item: "warning_preview", |
|
1369
|
|
|
title: $("#template_title").val(), |
|
1370
|
|
|
body: $("#template_body").val(), |
|
1371
|
|
|
user: $('input[name="u"]').attr("value") |
|
1372
|
|
|
}, |
|
1373
|
|
|
context: document.body |
|
1374
|
|
|
}) |
|
1375
|
|
|
.done(function(request) { |
|
1376
|
|
|
$("#box_preview").css({display:"block"}); |
|
1377
|
|
|
$("#template_preview").html($(request).find('body').text()); |
|
1378
|
|
|
|
|
1379
|
|
|
var $_errors = $("#errors"); |
|
1380
|
|
|
if ($(request).find("error").text() !== '') |
|
1381
|
|
|
{ |
|
1382
|
|
|
$_errors.css({display:"block"}); |
|
1383
|
|
|
|
|
1384
|
|
|
var errors_html = '', |
|
1385
|
|
|
errors = $(request).find('error').each(function() { |
|
|
|
|
|
|
1386
|
|
|
errors_html += $(this).text() + '<br />'; |
|
1387
|
|
|
}); |
|
1388
|
|
|
|
|
1389
|
|
|
$(document).find("#error_list").html(errors_html); |
|
1390
|
|
|
$('html, body').animate({ scrollTop: $_errors.offset().top }, 'slow'); |
|
1391
|
|
|
} |
|
1392
|
|
|
else |
|
1393
|
|
|
{ |
|
1394
|
|
|
$_errors.css({display:"none"}); |
|
1395
|
|
|
$("#error_list").html(''); |
|
1396
|
|
|
$('html, body').animate({ scrollTop: $("#box_preview").offset().top }, 'slow'); |
|
1397
|
|
|
} |
|
1398
|
|
|
|
|
1399
|
|
|
return false; |
|
1400
|
|
|
}); |
|
1401
|
|
|
|
|
1402
|
|
|
return false; |
|
1403
|
|
|
} |
|
1404
|
|
|
|
|
1405
|
|
|
/** |
|
1406
|
|
|
* Sets up all the js events for edit and save board-specific permission |
|
1407
|
|
|
* profiles |
|
1408
|
|
|
*/ |
|
1409
|
|
|
function initEditProfileBoards() |
|
1410
|
|
|
{ |
|
1411
|
|
|
$('.edit_all_board_profiles').on('click', function(e) { |
|
1412
|
|
|
e.preventDefault(); |
|
1413
|
|
|
|
|
1414
|
|
|
$('.edit_board').off('click.elkarte'); |
|
1415
|
|
|
}); |
|
1416
|
|
|
|
|
1417
|
|
|
$('.edit_board').show().on('click.elkarte', function(e) { |
|
1418
|
|
|
var $icon = $(this), |
|
1419
|
|
|
board_id = $icon.data('boardid'), |
|
1420
|
|
|
board_profile = $icon.data('boardprofile'), |
|
1421
|
|
|
$target = $('#edit_board_' + board_id), |
|
1422
|
|
|
$select = $('<select />') |
|
1423
|
|
|
.attr('name', 'boardprofile[' + board_id + ']') |
|
1424
|
|
|
.change(function() { |
|
1425
|
|
|
$(this).find('option:selected').each(function() { |
|
1426
|
|
|
if ($(this).attr('value') == board_profile) |
|
1427
|
|
|
$icon.addClass('nochanges').removeClass('changed'); |
|
|
|
|
|
|
1428
|
|
|
else |
|
1429
|
|
|
$icon.addClass('changed').removeClass('nochanges'); |
|
1430
|
|
|
}); |
|
1431
|
|
|
}); |
|
1432
|
|
|
|
|
1433
|
|
|
e.preventDefault(); |
|
1434
|
|
|
$(permission_profiles).each(function(key, value) { |
|
1435
|
|
|
var $opt = $('<option />').attr('value', value.id).text(value.name); |
|
1436
|
|
|
|
|
1437
|
|
|
if (value.id == board_profile) |
|
1438
|
|
|
$opt.attr('selected', 'selected'); |
|
|
|
|
|
|
1439
|
|
|
|
|
1440
|
|
|
$select.append($opt); |
|
1441
|
|
|
}); |
|
1442
|
|
|
|
|
1443
|
|
|
$target.replaceWith($select); |
|
1444
|
|
|
$select.change(); |
|
1445
|
|
|
|
|
1446
|
|
|
$('.edit_all_board_profiles').replaceWith($('<input type="submit" class="right_submit" />') |
|
1447
|
|
|
.attr('name', 'save_changes') |
|
1448
|
|
|
.attr('value', txt_save) |
|
1449
|
|
|
); |
|
1450
|
|
|
$icon.off('click.elkarte').on('click', function(e) { |
|
1451
|
|
|
e.preventDefault(); |
|
1452
|
|
|
if ($(this).hasClass('changed')) |
|
1453
|
|
|
$('input[name="save_changes"]').off('click'); |
|
|
|
|
|
|
1454
|
|
|
}); |
|
1455
|
|
|
}); |
|
1456
|
|
|
} |
|
1457
|
|
|
|
|
1458
|
|
|
/** |
|
1459
|
|
|
* Creates the image and attaches the event to convert the name of the permission |
|
1460
|
|
|
* profile into an input to change its name and back. |
|
1461
|
|
|
* |
|
1462
|
|
|
* It also removes the "Rename all" and "Remove Selected" buttons |
|
1463
|
|
|
* and the "Delete" column for consistency |
|
1464
|
|
|
*/ |
|
1465
|
|
|
function initEditPermissionProfiles() |
|
1466
|
|
|
{ |
|
1467
|
|
|
// We need a variable to be sure we are going to create only 1 cancel button |
|
1468
|
|
|
var run_once = false; |
|
1469
|
|
|
|
|
1470
|
|
|
$('.rename_profile').each(function() { |
|
1471
|
|
|
var $this_profile = $(this); |
|
1472
|
|
|
|
|
1473
|
|
|
$this_profile.after($('<a class="js-ed edit_board" />').attr('href', '#').on('click', function(ev) { |
|
1474
|
|
|
ev.preventDefault(); |
|
1475
|
|
|
|
|
1476
|
|
|
// If we have already created the cancel let's skip it |
|
1477
|
|
|
if (!run_once) |
|
1478
|
|
|
{ |
|
1479
|
|
|
var $cancel; |
|
1480
|
|
|
|
|
1481
|
|
|
run_once = true; |
|
1482
|
|
|
$cancel = $('<a class="js-ed-rm linkbutton" />').on('click', function(ev) { |
|
1483
|
|
|
ev.preventDefault(); |
|
1484
|
|
|
|
|
1485
|
|
|
// js-ed is hopefully a class introduced by this function only |
|
1486
|
|
|
// Any element with this class will be restored when cancel is clicked |
|
1487
|
|
|
$('.js-ed').show(); |
|
1488
|
|
|
|
|
1489
|
|
|
// js-ed-rm is again a class introduced by this function |
|
1490
|
|
|
// Any element with this class will be removed when cancelling |
|
1491
|
|
|
$('.js-ed-rm').remove(); |
|
1492
|
|
|
|
|
1493
|
|
|
// The cancel button is removed as well, |
|
1494
|
|
|
// so we need to generate it again later (if we need it again) |
|
1495
|
|
|
run_once = false; |
|
1496
|
|
|
|
|
1497
|
|
|
$('#rename').val(txt_permissions_profile_rename); |
|
1498
|
|
|
}).text(ajax_notification_cancel_text).attr('href', '#'); |
|
1499
|
|
|
} |
|
1500
|
|
|
|
|
1501
|
|
|
$this_profile.after($('<input type="text" class="js-ed-rm input_text" />') |
|
1502
|
|
|
.attr('name', 'rename_profile[' + $this_profile.data('pid') + ']') |
|
1503
|
|
|
.val($this_profile.text())); |
|
1504
|
|
|
|
|
1505
|
|
|
// These will have to pop back hitting cancel, so let's prepare them |
|
1506
|
|
|
$('#rename').addClass('js-ed').val(txt_permissions_commit).before($cancel); |
|
|
|
|
|
|
1507
|
|
|
$this_profile.addClass('js-ed').hide(); |
|
1508
|
|
|
$('#delete').addClass('js-ed').hide(); |
|
1509
|
|
|
$('.perm_profile_delete').addClass('js-ed').hide(); |
|
1510
|
|
|
$(this).hide(); |
|
1511
|
|
|
})); |
|
1512
|
|
|
}); |
|
1513
|
|
|
} |
|
1514
|
|
|
|
|
1515
|
|
|
/** |
|
1516
|
|
|
* Attach the AJAX handling of things to the various themes to remove |
|
1517
|
|
|
* Used in ManageThemes (template_list_themes) |
|
1518
|
|
|
*/ |
|
1519
|
|
|
function initDeleteThemes() |
|
1520
|
|
|
{ |
|
1521
|
|
|
$(".delete_theme").on("click", function (event) { |
|
1522
|
|
|
event.preventDefault(); |
|
1523
|
|
|
var theme_id = $(this).data("theme_id"), |
|
1524
|
|
|
base_url = $(this).attr("href"), |
|
1525
|
|
|
pattern = new RegExp(elk_session_var + "=" + elk_session_id + ";(.*)$"), |
|
1526
|
|
|
tokens = pattern.exec(base_url)[1].split("="), |
|
1527
|
|
|
token = tokens[1], |
|
1528
|
|
|
token_var = tokens[0]; |
|
1529
|
|
|
|
|
1530
|
|
|
if (confirm(txt_theme_remove_confirm)) |
|
|
|
|
|
|
1531
|
|
|
{ |
|
1532
|
|
|
$.ajax({ |
|
1533
|
|
|
type: "GET", |
|
1534
|
|
|
url: base_url + ";api;xml", |
|
1535
|
|
|
beforeSend: ajax_indicator(true) |
|
1536
|
|
|
}) |
|
1537
|
|
|
.done(function(request) { |
|
1538
|
|
|
if ($(request).find("error").length === 0) |
|
1539
|
|
|
{ |
|
1540
|
|
|
var new_token = $(request).find("token").text(), |
|
1541
|
|
|
new_token_var = $(request).find("token_var").text(); |
|
1542
|
|
|
|
|
1543
|
|
|
$(".theme_" + theme_id).slideToggle("slow", function () { |
|
1544
|
|
|
$(this).remove(); |
|
1545
|
|
|
}); |
|
1546
|
|
|
|
|
1547
|
|
|
$(".delete_theme").each(function () { |
|
1548
|
|
|
$(this).attr("href", $(this).attr("href").replace(token_var + "=" + token, new_token_var + "=" + new_token)); |
|
1549
|
|
|
}); |
|
1550
|
|
|
} |
|
1551
|
|
|
// @todo improve error handling |
|
1552
|
|
|
else |
|
1553
|
|
|
{ |
|
1554
|
|
|
alert($(request).find("text").text()); |
|
|
|
|
|
|
1555
|
|
|
// Redirect to the delete theme page, though it will result in a token verification error |
|
1556
|
|
|
window.location = base_url; |
|
1557
|
|
|
} |
|
1558
|
|
|
}) |
|
1559
|
|
|
.fail(function(request) { |
|
|
|
|
|
|
1560
|
|
|
window.location = base_url; |
|
1561
|
|
|
}) |
|
1562
|
|
|
.always(function() { |
|
1563
|
|
|
// turn off the indicator |
|
1564
|
|
|
ajax_indicator(false); |
|
1565
|
|
|
}); |
|
1566
|
|
|
} |
|
1567
|
|
|
}); |
|
1568
|
|
|
} |
|
1569
|
|
|
|
|
1570
|
|
|
/** |
|
1571
|
|
|
* These two functions (navigatePreview and refreshPreview) are used in ManageThemes |
|
1572
|
|
|
* (template_edit_style) to create a preview of the site with the changed stylesheets |
|
1573
|
|
|
* |
|
1574
|
|
|
* @param {string} url |
|
1575
|
|
|
*/ |
|
1576
|
|
|
function navigatePreview(url) |
|
1577
|
|
|
{ |
|
1578
|
|
|
var myDoc = new XMLHttpRequest(); |
|
1579
|
|
|
|
|
1580
|
|
|
myDoc.onreadystatechange = function () |
|
1581
|
|
|
{ |
|
1582
|
|
|
if (myDoc.readyState !== 4) |
|
1583
|
|
|
return; |
|
|
|
|
|
|
1584
|
|
|
|
|
1585
|
|
|
if (myDoc.responseText !== null && myDoc.status === 200) |
|
1586
|
|
|
{ |
|
1587
|
|
|
previewData = myDoc.responseText; |
|
1588
|
|
|
document.getElementById('css_preview_box').style.display = "block"; |
|
1589
|
|
|
|
|
1590
|
|
|
// Revert to the theme they actually use ;). |
|
1591
|
|
|
var tempImage = new Image(); |
|
1592
|
|
|
tempImage.src = elk_prepareScriptUrl(elk_scripturl) + 'action=admin;area=theme;sa=edit;theme=' + theme_id + ';preview;' + (new Date().getTime()); |
|
1593
|
|
|
|
|
1594
|
|
|
refreshPreviewCache = null; |
|
1595
|
|
|
refreshPreview(false); |
|
1596
|
|
|
} |
|
1597
|
|
|
}; |
|
1598
|
|
|
|
|
1599
|
|
|
var anchor = ""; |
|
1600
|
|
|
if (url.indexOf("#") !== -1) |
|
1601
|
|
|
{ |
|
1602
|
|
|
anchor = url.substr(url.indexOf("#")); |
|
1603
|
|
|
url = url.substr(0, url.indexOf("#")); |
|
1604
|
|
|
} |
|
1605
|
|
|
|
|
1606
|
|
|
myDoc.open("GET", url + (url.indexOf("?") === -1 ? "?" : ";") + 'theme=' + theme_id + anchor, true); |
|
1607
|
|
|
myDoc.send(null); |
|
1608
|
|
|
} |
|
1609
|
|
|
|
|
1610
|
|
|
/** |
|
1611
|
|
|
* Used when editing a stylesheet. Allows for the preview to be updated to reflect |
|
1612
|
|
|
* changes made to the css in the editor. |
|
1613
|
|
|
* |
|
1614
|
|
|
* @param {boolean} check |
|
1615
|
|
|
*/ |
|
1616
|
|
|
function refreshPreview(check) |
|
1617
|
|
|
{ |
|
1618
|
|
|
var identical = document.forms.stylesheetForm.entire_file.value == refreshPreviewCache; |
|
1619
|
|
|
|
|
1620
|
|
|
// Don't reflow the whole thing if nothing changed!! |
|
1621
|
|
|
if (check && identical) |
|
1622
|
|
|
return; |
|
|
|
|
|
|
1623
|
|
|
|
|
1624
|
|
|
refreshPreviewCache = document.forms.stylesheetForm.entire_file.value; |
|
1625
|
|
|
|
|
1626
|
|
|
// Replace the paths for images. |
|
1627
|
|
|
refreshPreviewCache = refreshPreviewCache.replace(/url\(\.\.\/images/gi, "url(" + elk_images_url); |
|
1628
|
|
|
|
|
1629
|
|
|
// Try to do it without a complete reparse. |
|
1630
|
|
|
if (identical) |
|
1631
|
|
|
{ |
|
1632
|
|
|
try |
|
1633
|
|
|
{ |
|
1634
|
|
|
if (is_ie) |
|
|
|
|
|
|
1635
|
|
|
{ |
|
1636
|
|
|
var sheets = frames['css_preview_box'].document.styleSheets; |
|
1637
|
|
|
for (var j = 0; j < sheets.length; j++) |
|
1638
|
|
|
{ |
|
1639
|
|
|
if (sheets[j].id === 'css_preview_box') |
|
1640
|
|
|
sheets[j].cssText = document.forms.stylesheetForm.entire_file.value; |
|
|
|
|
|
|
1641
|
|
|
} |
|
1642
|
|
|
} |
|
1643
|
|
|
else |
|
1644
|
|
|
{ |
|
1645
|
|
|
frames['css_preview_box'].document.getElementById("css_preview_sheet").innerHTML = document.forms.stylesheetForm.entire_file.value; |
|
1646
|
|
|
} |
|
1647
|
|
|
} |
|
1648
|
|
|
catch (e) |
|
1649
|
|
|
{ |
|
1650
|
|
|
identical = false; |
|
1651
|
|
|
} |
|
1652
|
|
|
} |
|
1653
|
|
|
|
|
1654
|
|
|
// This will work most of the time... could be done with an after-apply, maybe. |
|
1655
|
|
|
if (!identical) |
|
1656
|
|
|
{ |
|
1657
|
|
|
var data = previewData, |
|
1658
|
|
|
preview_sheet = document.forms.stylesheetForm.entire_file.value, |
|
1659
|
|
|
stylesheetMatch = new RegExp('<link rel="stylesheet"[^>]+href="[^"]+' + editFilename + '[^>]*>'), |
|
1660
|
|
|
iframe; |
|
1661
|
|
|
|
|
1662
|
|
|
// Replace the paths for images. |
|
1663
|
|
|
preview_sheet = preview_sheet.replace(/url\(\.\.\/images/gi, "url(" + elk_images_url); |
|
1664
|
|
|
data = data.replace(stylesheetMatch, '<style type="text/css" id="css_preview_sheet">' + preview_sheet + "<" + "/style>"); |
|
1665
|
|
|
|
|
1666
|
|
|
iframe = document.getElementById("css_preview_box"); |
|
1667
|
|
|
iframe.contentWindow.document.open(); |
|
1668
|
|
|
iframe.contentWindow.document.write(data); |
|
1669
|
|
|
iframe.contentWindow.document.close(); |
|
1670
|
|
|
|
|
1671
|
|
|
// Next, fix all its links so we can handle them and reapply the new css! |
|
1672
|
|
|
iframe.onload = function () |
|
1673
|
|
|
{ |
|
1674
|
|
|
var fixLinks = frames["css_preview_box"].document.getElementsByTagName("a"); |
|
1675
|
|
|
for (var i = 0; i < fixLinks.length; i++) |
|
1676
|
|
|
{ |
|
1677
|
|
|
if (fixLinks[i].onclick) |
|
1678
|
|
|
continue; |
|
|
|
|
|
|
1679
|
|
|
|
|
1680
|
|
|
fixLinks[i].onclick = function () |
|
1681
|
|
|
{ |
|
1682
|
|
|
window.parent.navigatePreview(this.href); |
|
1683
|
|
|
return false; |
|
1684
|
|
|
}; |
|
1685
|
|
|
} |
|
1686
|
|
|
}; |
|
1687
|
|
|
} |
|
1688
|
|
|
} |
|
1689
|
|
|
|
|
1690
|
|
|
/** |
|
1691
|
|
|
* Callback (onBeforeUpdate) used by the AutoSuggest, used when adding new bans |
|
1692
|
|
|
* |
|
1693
|
|
|
* @param {object} oAutoSuggest |
|
1694
|
|
|
*/ |
|
1695
|
|
|
function onUpdateName(oAutoSuggest) |
|
|
|
|
|
|
1696
|
|
|
{ |
|
1697
|
|
|
document.getElementById('user_check').checked = true; |
|
1698
|
|
|
return true; |
|
1699
|
|
|
} |
|
1700
|
|
|
|
|
1701
|
|
|
/** |
|
1702
|
|
|
* Validates that the ban form is filled out properly before submitting |
|
1703
|
|
|
* Used when editing bans |
|
1704
|
|
|
* |
|
1705
|
|
|
* @param {object} aForm this form object to check |
|
1706
|
|
|
*/ |
|
1707
|
|
|
function confirmBan(aForm) |
|
1708
|
|
|
{ |
|
1709
|
|
|
if (aForm.ban_name.value === '') |
|
1710
|
|
|
{ |
|
1711
|
|
|
alert(txt_ban_name_empty); |
|
|
|
|
|
|
1712
|
|
|
return false; |
|
1713
|
|
|
} |
|
1714
|
|
|
|
|
1715
|
|
|
if (aForm.partial_ban.checked && !(aForm.cannot_post.checked || aForm.cannot_register.checked || aForm.cannot_login.checked)) |
|
1716
|
|
|
{ |
|
1717
|
|
|
alert(txt_ban_restriction_empty); |
|
1718
|
|
|
return false; |
|
1719
|
|
|
} |
|
1720
|
|
|
|
|
1721
|
|
|
return true; |
|
1722
|
|
|
} |
|
1723
|
|
|
|
|
1724
|
|
|
// Enable/disable some fields when working with bans. |
|
1725
|
|
|
var fUpdateStatus = function () |
|
1726
|
|
|
{ |
|
1727
|
|
|
document.getElementById("expire_date").disabled = !document.getElementById("expires_one_day").checked; |
|
1728
|
|
|
document.getElementById("cannot_post").disabled = document.getElementById("full_ban").checked; |
|
1729
|
|
|
document.getElementById("cannot_register").disabled = document.getElementById("full_ban").checked; |
|
1730
|
|
|
document.getElementById("cannot_login").disabled = document.getElementById("full_ban").checked; |
|
1731
|
|
|
}; |
|
1732
|
|
|
|
|
1733
|
|
|
/** |
|
1734
|
|
|
* Used when setting up subscriptions, used to toggle the currency code divs |
|
1735
|
|
|
* based on which currencies are chosen. |
|
1736
|
|
|
*/ |
|
1737
|
|
|
function toggleCurrencyOther() |
|
1738
|
|
|
{ |
|
1739
|
|
|
var otherOn = document.getElementById("paid_currency").value === 'other', |
|
1740
|
|
|
currencydd = document.getElementById("custom_currency_code_div_dd"); |
|
1741
|
|
|
|
|
1742
|
|
|
if (otherOn) |
|
1743
|
|
|
{ |
|
1744
|
|
|
document.getElementById("custom_currency_code_div").style.display = ""; |
|
1745
|
|
|
document.getElementById("custom_currency_symbol_div").style.display = ""; |
|
1746
|
|
|
|
|
1747
|
|
|
if (currencydd) |
|
1748
|
|
|
{ |
|
1749
|
|
|
document.getElementById("custom_currency_code_div_dd").style.display = ""; |
|
1750
|
|
|
document.getElementById("custom_currency_symbol_div_dd").style.display = ""; |
|
1751
|
|
|
} |
|
1752
|
|
|
} |
|
1753
|
|
|
else |
|
1754
|
|
|
{ |
|
1755
|
|
|
document.getElementById("custom_currency_code_div").style.display = "none"; |
|
1756
|
|
|
document.getElementById("custom_currency_symbol_div").style.display = "none"; |
|
1757
|
|
|
|
|
1758
|
|
|
if (currencydd) |
|
1759
|
|
|
{ |
|
1760
|
|
|
document.getElementById("custom_currency_symbol_div_dd").style.display = "none"; |
|
1761
|
|
|
document.getElementById("custom_currency_code_div_dd").style.display = "none"; |
|
1762
|
|
|
} |
|
1763
|
|
|
} |
|
1764
|
|
|
} |
|
1765
|
|
|
|
|
1766
|
|
|
/** |
|
1767
|
|
|
* Used to ajax-ively preview the templates of bounced emails (template_bounce_template) |
|
1768
|
|
|
*/ |
|
1769
|
|
|
function ajax_getEmailTemplatePreview() |
|
1770
|
|
|
{ |
|
1771
|
|
|
$.ajax({ |
|
1772
|
|
|
type: "POST", |
|
1773
|
|
|
url: elk_scripturl + "?action=xmlpreview;xml", |
|
1774
|
|
|
data: { |
|
1775
|
|
|
item: "bounce_preview", |
|
1776
|
|
|
title: $("#template_title").val(), |
|
1777
|
|
|
body: $("#template_body").val() |
|
1778
|
|
|
}, |
|
1779
|
|
|
context: document.body |
|
1780
|
|
|
}) |
|
1781
|
|
|
.done(function(request) { |
|
1782
|
|
|
// Show the preview section, populated with the response |
|
1783
|
|
|
$("#preview_section").css({display: "block"}); |
|
1784
|
|
|
$("#preview_body").html($(request).find('body').text()); |
|
1785
|
|
|
$("#preview_subject").html($(request).find('subject').text()); |
|
1786
|
|
|
|
|
1787
|
|
|
// Any error we need to let them know about? |
|
1788
|
|
|
if ($(request).find("error").text() !== '') |
|
1789
|
|
|
{ |
|
1790
|
|
|
var errors_html = '', |
|
1791
|
|
|
$_errors = $("#errors"), |
|
1792
|
|
|
errors; |
|
1793
|
|
|
|
|
1794
|
|
|
// Build the error string |
|
1795
|
|
|
errors = $(request).find('error').each(function() { |
|
|
|
|
|
|
1796
|
|
|
errors_html += $(this).text() + '<br />'; |
|
1797
|
|
|
}); |
|
1798
|
|
|
|
|
1799
|
|
|
// Add it to the error div, set the class level, and show it |
|
1800
|
|
|
$(document).find("#error_list").html(errors_html); |
|
1801
|
|
|
$_errors.css({display: ""}); |
|
1802
|
|
|
$_errors.attr('class', parseInt($(request).find('errors').attr('serious')) === 0 ? 'warningbox' : 'errorbox'); |
|
1803
|
|
|
} |
|
1804
|
|
|
else |
|
1805
|
|
|
{ |
|
1806
|
|
|
$("#errors").css({display: "none"}); |
|
1807
|
|
|
$("#error_list").html(''); |
|
1808
|
|
|
} |
|
1809
|
|
|
|
|
1810
|
|
|
// Navigate to the preview |
|
1811
|
|
|
$('html, body').animate({ scrollTop: $('#preview_section').offset().top }, 'slow'); |
|
1812
|
|
|
|
|
1813
|
|
|
return false; |
|
1814
|
|
|
}); |
|
1815
|
|
|
|
|
1816
|
|
|
return false; |
|
1817
|
|
|
} |
|
1818
|
|
|
|
|
1819
|
|
|
/** |
|
1820
|
|
|
* Used to ajax-ively preview a word censor |
|
1821
|
|
|
* Does no checking, it either gets a result or does nothing |
|
1822
|
|
|
*/ |
|
1823
|
|
|
function ajax_getCensorPreview() |
|
1824
|
|
|
{ |
|
1825
|
|
|
$.ajax({ |
|
1826
|
|
|
type: 'POST', |
|
1827
|
|
|
dataType: 'json', |
|
1828
|
|
|
url: elk_scripturl + "?action=admin;area=postsettings;sa=censor;xml", |
|
1829
|
|
|
data: { |
|
1830
|
|
|
censortest: $("#censortest").val() |
|
1831
|
|
|
} |
|
1832
|
|
|
}) |
|
1833
|
|
|
.done(function(request) { |
|
1834
|
|
|
if (request.result === true) { |
|
1835
|
|
|
// Show the censored text section, populated with the response |
|
1836
|
|
|
$("#censor_result").css({display: "block"}).html(request.censor); |
|
1837
|
|
|
|
|
1838
|
|
|
// Update the token |
|
1839
|
|
|
$("#token").attr({name:request.token_val, value:request.token}); |
|
1840
|
|
|
|
|
1841
|
|
|
// Clear the box |
|
1842
|
|
|
$('#censortest').attr({value:''}).val(''); |
|
1843
|
|
|
} |
|
1844
|
|
|
}); |
|
1845
|
|
|
|
|
1846
|
|
|
return false; |
|
1847
|
|
|
} |
|
1848
|
|
|
|
|
1849
|
|
|
/** |
|
1850
|
|
|
* Used to show/hide sub options for the various notifications |
|
1851
|
|
|
* action=admin;area=featuresettings;sa=mention |
|
1852
|
|
|
*/ |
|
1853
|
|
|
$(function() { |
|
1854
|
|
|
var $headers = $("#mention").find("input[id^='notifications'][id$='[notification]']"); |
|
1855
|
|
|
|
|
1856
|
|
|
$headers.change(function() { |
|
1857
|
|
|
var $top = $(this).closest('dl'), |
|
1858
|
|
|
$hparent = $(this).parent(); |
|
1859
|
|
|
|
|
1860
|
|
|
if (this.checked) |
|
1861
|
|
|
{ |
|
1862
|
|
|
$top.find('dt:not(:first-child)').fadeIn(); |
|
1863
|
|
|
$top.find('dd:not(:nth-child(2))').each(function() { |
|
1864
|
|
|
$(this).fadeIn(); |
|
1865
|
|
|
$(this).find('input').prop('disabled', false); |
|
1866
|
|
|
}); |
|
1867
|
|
|
} |
|
1868
|
|
|
else |
|
1869
|
|
|
{ |
|
1870
|
|
|
$top.find('dt:not(:first-child)').hide(); |
|
1871
|
|
|
$top.find('dd:not(:nth-child(2))').each(function() { |
|
1872
|
|
|
$(this).hide(); |
|
1873
|
|
|
$(this).find('input').prop('disabled', true); |
|
1874
|
|
|
}); |
|
1875
|
|
|
} |
|
1876
|
|
|
|
|
1877
|
|
|
$hparent.show(); |
|
1878
|
|
|
$hparent.prev().show(); |
|
1879
|
|
|
}); |
|
1880
|
|
|
|
|
1881
|
|
|
$headers.change(); |
|
1882
|
|
|
}); |
|
1883
|
|
|
|
|
1884
|
|
|
/** |
|
1885
|
|
|
* Ajax function to clear CSS and JS hives. Called from action=admin;area=featuresettings;sa=basic |
|
1886
|
|
|
* Remove Hives button. |
|
1887
|
|
|
*/ |
|
1888
|
|
|
$(function() { |
|
1889
|
|
|
$('#clean_hives').on('click', function () { |
|
1890
|
|
|
var infoBar = new ElkInfoBar('bar_clean_hives'); |
|
1891
|
|
|
|
|
1892
|
|
|
$.ajax({ |
|
1893
|
|
|
type: 'POST', |
|
1894
|
|
|
dataType: 'json', |
|
1895
|
|
|
url: elk_scripturl + "?action=admin;area=featuresettings;sa=basic;xml;api=json", |
|
1896
|
|
|
data: { |
|
1897
|
|
|
cleanhives: true |
|
1898
|
|
|
} |
|
1899
|
|
|
}) |
|
1900
|
|
|
.done(function(request) { |
|
1901
|
|
|
infoBar.changeText(request.response); |
|
1902
|
|
|
|
|
1903
|
|
|
if (request.success === true) { |
|
1904
|
|
|
infoBar.isSuccess(); |
|
1905
|
|
|
} |
|
1906
|
|
|
else { |
|
1907
|
|
|
infoBar.isError(); |
|
1908
|
|
|
} |
|
1909
|
|
|
}) |
|
1910
|
|
|
.fail(function(request) { |
|
|
|
|
|
|
1911
|
|
|
infoBar.isError(); |
|
1912
|
|
|
infoBar.changeText(txt_invalid_response); |
|
1913
|
|
|
}) |
|
1914
|
|
|
.always(function(request) { |
|
|
|
|
|
|
1915
|
|
|
infoBar.showBar(); |
|
1916
|
|
|
}); |
|
1917
|
|
|
|
|
1918
|
|
|
return false; |
|
1919
|
|
|
}); |
|
1920
|
|
|
}); |
|
1921
|
|
|
|
|
1922
|
|
|
/** |
|
1923
|
|
|
* Enable / disable "core" features of the software. Called from action=admin;area=corefeatures |
|
1924
|
|
|
*/ |
|
1925
|
|
|
$(function() { |
|
1926
|
|
|
if ($('#core_features').length === 0) |
|
1927
|
|
|
{ |
|
1928
|
|
|
return; |
|
1929
|
|
|
} |
|
1930
|
|
|
|
|
1931
|
|
|
$(".core_features_hide").css('display', 'none'); |
|
1932
|
|
|
$(".core_features_img").show().css({'cursor': 'pointer'}).each(function() { |
|
1933
|
|
|
var sImageText = $(this).hasClass('on') ? feature_on_text : feature_off_text; |
|
1934
|
|
|
$(this).attr({ title: sImageText, alt: sImageText }); |
|
1935
|
|
|
}); |
|
1936
|
|
|
$("#core_features_submit").css('display', 'none'); |
|
1937
|
|
|
|
|
1938
|
|
|
if (!token_name) |
|
|
|
|
|
|
1939
|
|
|
token_name = $("#core_features_token").attr("name"); |
|
|
|
|
|
|
1940
|
|
|
|
|
1941
|
|
|
if (!token_value) |
|
|
|
|
|
|
1942
|
|
|
token_value = $("#core_features_token").attr("value"); |
|
|
|
|
|
|
1943
|
|
|
|
|
1944
|
|
|
// Attach our action to the core features power button |
|
1945
|
|
|
$(".core_features_img").click(function() { |
|
1946
|
|
|
var cc = $(this), |
|
1947
|
|
|
cf = $(this).attr("id").substring(7), |
|
1948
|
|
|
imgs = new Array(elk_images_url + "/admin/switch_off.png", elk_images_url + "/admin/switch_on.png"), |
|
|
|
|
|
|
1949
|
|
|
new_state = !$("#feature_" + cf).attr("checked"), |
|
1950
|
|
|
ajax_infobar = new ElkInfoBar('core_features_bar', {error_class: 'errorbox', success_class: 'successbox'}), |
|
1951
|
|
|
data; |
|
1952
|
|
|
|
|
1953
|
|
|
$("#feature_" + cf).attr("checked", new_state); |
|
1954
|
|
|
|
|
1955
|
|
|
data = {save: "save", feature_id: cf}; |
|
1956
|
|
|
data[$("#core_features_session").attr("name")] = $("#core_features_session").val(); |
|
1957
|
|
|
data[token_name] = token_value; |
|
1958
|
|
|
|
|
1959
|
|
|
$(".core_features_status_box").each(function(){ |
|
1960
|
|
|
data[$(this).attr("name")] = !$(this).attr("checked") ? 0 : 1; |
|
1961
|
|
|
}); |
|
1962
|
|
|
|
|
1963
|
|
|
// Launch AJAX request. |
|
1964
|
|
|
$.ajax({ |
|
1965
|
|
|
// The link we are accessing. |
|
1966
|
|
|
url: elk_scripturl + "?action=xmlhttp;sa=corefeatures;xml", |
|
1967
|
|
|
|
|
1968
|
|
|
// The type of request. |
|
1969
|
|
|
type: "post", |
|
1970
|
|
|
|
|
1971
|
|
|
// The type of data that is getting returned. |
|
1972
|
|
|
data: data |
|
1973
|
|
|
}) |
|
1974
|
|
|
.done(function(request) { |
|
1975
|
|
|
if ($(request).find("errors").find("error").length !== 0) |
|
1976
|
|
|
{ |
|
1977
|
|
|
ajax_infobar.isError(); |
|
1978
|
|
|
ajax_infobar.changeText($(request).find("errors").find("error").text()).showBar(); |
|
1979
|
|
|
} |
|
1980
|
|
|
else if ($(request).find("elk").length !== 0) |
|
1981
|
|
|
{ |
|
1982
|
|
|
$("#feature_link_" + cf).html($(request).find("corefeatures").find("corefeature").text()); |
|
1983
|
|
|
cc.attr({ |
|
1984
|
|
|
"src": imgs[new_state ? 1 : 0], |
|
1985
|
|
|
"title": new_state ? feature_on_text : feature_off_text, |
|
1986
|
|
|
"alt": new_state ? feature_on_text : feature_off_text |
|
1987
|
|
|
}); |
|
1988
|
|
|
$("#feature_link_" + cf).fadeOut().fadeIn(); |
|
1989
|
|
|
ajax_infobar.isSuccess(); |
|
1990
|
|
|
var message = $(request).find("messages").find("message").text(); |
|
1991
|
|
|
ajax_infobar.changeText(message).showBar(); |
|
1992
|
|
|
|
|
1993
|
|
|
token_name = $(request).find("tokens").find('[type="token"]').text(); |
|
|
|
|
|
|
1994
|
|
|
token_value = $(request).find("tokens").find('[type="token_var"]').text(); |
|
|
|
|
|
|
1995
|
|
|
} |
|
1996
|
|
|
else |
|
1997
|
|
|
{ |
|
1998
|
|
|
ajax_infobar.isError(); |
|
1999
|
|
|
ajax_infobar.changeText(core_settings_generic_error).showBar(); |
|
2000
|
|
|
} |
|
2001
|
|
|
}) |
|
2002
|
|
|
.fail(function(error) { |
|
2003
|
|
|
ajax_infobar.changeText(error).showBar(); |
|
2004
|
|
|
}); |
|
2005
|
|
|
}); |
|
2006
|
|
|
}); |
|
2007
|
|
|
|
|
2008
|
|
|
function confirmAgreement(text) { |
|
2009
|
|
|
if ($('#checkboxAcceptAgreement').is(':checked')) { |
|
2010
|
|
|
return confirm(text); |
|
|
|
|
|
|
2011
|
|
|
} |
|
2012
|
|
|
return true; |
|
2013
|
|
|
} |
|
2014
|
|
|
|
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.
Consider:
If you or someone else later decides to put another statement in, only the first statement will be executed.
In this case the statement
b = 42will always be executed, while the logging statement will be executed conditionally.ensures that the proper code will be executed conditionally no matter how many statements are added or removed.